785

When I try to print an instance of a class, I get an output like this:

>>> class Test():
...     def __init__(self):
...         self.a = 'foo'
...
>>> print(Test())
<__main__.Test object at 0x7fc9a9e36d60>

How can I make it so that the print will show something custom (e.g. something that includes the a attribute value)? That is, how can I can define how the instances of the class will appear when printed (their string representation)?


See How can I choose a custom string representation for a class itself (not instances of the class)? if you want to define the behaviour for the class itself (in this case, so that print(Test) shows something custom, rather than <class __main__.Test> or similar). (In fact, the technique is essentially the same, but trickier to apply.)

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Ashwin Nanjappa
  • 76,204
  • 83
  • 211
  • 292

12 Answers12

891
>>> class Test:
...     def __repr__(self):
...         return "Test()"
...     def __str__(self):
...         return "member of Test"
... 
>>> t = Test()
>>> t
Test()
>>> print(t)
member of Test

The __str__ method is what gets called happens when you print it, and the __repr__ method is what happens when you use the repr() function (or when you look at it with the interactive prompt).

If no __str__ method is given, Python will print the result of __repr__ instead. If you define __str__ but not __repr__, Python will use what you see above as the __repr__, but still use __str__ for printing.

Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
Chris Lutz
  • 73,191
  • 16
  • 130
  • 183
  • 13
    there's also a __unicode__ method, which you can use instead of __Str__ ; note that it should return a unicode object, not a string (but if you return a string, the conversion to unicode will be done anyway...) – kender Oct 08 '09 at 05:32
  • 1
    @kender - I didn't know about it, but in retrospect it makes perfect sense given Python 2.x's broken Unicode handling. – Chris Lutz Oct 08 '09 at 05:36
  • 14
    I think this answer cannot be completed without a link to [this other one](http://stackoverflow.com/a/2626364/68269)! – tnotstar Dec 20 '12 at 11:15
  • Saved me! However, after re-implementing the method __repr__(self), print will mislead users. Are you aware of any best practices around this? – Viet Jul 05 '13 at 03:25
  • 15
    To Java programmers: __str__(self) is like the toString() of the python world – Janac Meena Jul 18 '16 at 20:30
  • looks like this is not the case in python3.6 at least to what I'm using – Sajuuk Mar 26 '18 at 08:34
  • What if you can't edit the class you want to get information about?.. like something in a shared library / plugin? Surely there must be some kind of generic class method reflection available that doesn't require config? – geoidesic Apr 20 '18 at 13:12
183

As Chris Lutz explains, this is defined by the __repr__ method in your class.

From the documentation of repr():

For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a __repr__() method.

Given the following class Test:

class Test:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __repr__(self):
        return f"<Test a:{self.a} b:{self.b}>"

    def __str__(self):
        return f"From str method of Test: a is {self.a}, b is {self.b}"

..it will act the following way in the Python shell:

>>> t = Test(123, 456)
>>> t
<Test a:123 b:456>
>>> print(repr(t))
<Test a:123 b:456>
>>> print(t)
From str method of Test: a is 123, b is 456
>>> print(str(t))
From str method of Test: a is 123, b is 456

If no __str__ method is defined, print(t) (or print(str(t))) will use the result of __repr__ instead

If no __repr__ method is defined then the default is used, which is roughly equivalent to:

def __repr__(self):
    cls = self.__class__
    return f"<{cls.__module_}.{cls.__qualname__} object at {id(self)}>"
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
dbr
  • 165,801
  • 69
  • 278
  • 343
  • +1 but your class code's `__str__` is different from the interactive shell's results you give. :P – Chris Lutz Oct 08 '09 at 03:05
  • 1
    Err, oops.. manually modifying REPL output never ends well. I should probably doctest my posts :P – dbr Oct 08 '09 at 03:29
  • Thanks. But, the string formatting type (%) in your example is deprecated. Could you change to the str.format() type? :-) – Ashwin Nanjappa Oct 08 '09 at 07:16
  • 1
    The `%` string formatting isn't deprecated, from http://docs.python.org/whatsnew/2.6.html "the % operator is *supplemented* by a more powerful string formatting method, format()" – dbr Oct 08 '09 at 14:32
  • 4
    Dbr: That is true. Do note that the "What's New In Python 3.0" doc also says "format() method [...] The plan is to eventually make this the only API for string formatting, and to start deprecating the % operator in Python 3.1." – Ashwin Nanjappa Oct 09 '09 at 06:03
  • 1
    Pitty, `%`'s been very convenient. – Janusz Lenar Dec 12 '11 at 21:28
  • This won't work if the object is inside another data structure, try: `print([Test(123)])` – Hendy Irawan Nov 21 '17 at 14:10
101

If you're in a situation like @Keith you could try:

print(a.__dict__)

It goes against what I would consider good style but if you're just trying to debug then it should do what you want.

John
  • 1,837
  • 1
  • 8
  • 12
81

A generic way that can be applied to any class without specific formatting could be done as follows:

class Element:
    def __init__(self, name, symbol, number):
        self.name = name
        self.symbol = symbol
        self.number = number

    def __str__(self):
        return str(self.__class__) + ": " + str(self.__dict__)

And then,

elem = Element('my_name', 'some_symbol', 3)
print(elem)

produces

__main__.Element: {'symbol': 'some_symbol', 'name': 'my_name', 'number': 3}
user394430
  • 2,805
  • 2
  • 28
  • 27
21

A prettier version of response by @user394430

class Element:
    def __init__(self, name, symbol, number):
        self.name = name
        self.symbol = symbol
        self.number = number

    def __str__(self):
        return  str(self.__class__) + '\n'+ '\n'.join(('{} = {}'.format(item, self.__dict__[item]) for item in self.__dict__))

elem = Element('my_name', 'some_symbol', 3)
print(elem)

Produces visually nice list of the names and values.

<class '__main__.Element'>
name = my_name
symbol = some_symbol
number = 3

An even fancier version (thanks Ruud) sorts the items:

def __str__(self):
    return  str(self.__class__) + '\n' + '\n'.join((str(item) + ' = ' + str(self.__dict__[item]) for item in sorted(self.__dict__)))
Mike from PSG
  • 5,312
  • 21
  • 39
  • return ','.join(('{} = {}'.format(item, self.__dict__[item]) for item in self.__dict__)) .........puts everyting on one line. I removed the class name, I just wanted to print the values for purpose of debugging – SleepyBoBos Mar 03 '21 at 20:23
18

Simple. In the print, do:

print(foobar.__dict__)

as long as the constructor is

__init__
Alon
  • 191
  • 2
  • 9
  • Partially interesting. It's fast and "builtin" but is limited to basic value type. A new class object inside will display the class type not the content. So helpfull and interesting too use but not exhaustive compare to the request like _str__ and __repr__ do. – NeronLeVelu May 29 '22 at 13:37
15

For Python 3:

If the specific format isn't important (e.g. for debugging) just inherit from the Printable class below. No need to write code for every object.

Inspired by this answer

class Printable:
    def __repr__(self):
        from pprint import pformat
        return "<" + type(self).__name__ + "> " + pformat(vars(self), indent=4, width=1)

# Example Usage
class MyClass(Printable):
    pass

my_obj = MyClass()
my_obj.msg = "Hello"
my_obj.number = "46"
print(my_obj)
Community
  • 1
  • 1
PeterM
  • 2,372
  • 1
  • 26
  • 35
14

Just to add my two cents to @dbr's answer, following is an example of how to implement this sentence from the official documentation he's cited:

"[...] to return a string that would yield an object with the same value when passed to eval(), [...]"

Given this class definition:

class Test(object):
    def __init__(self, a, b):
        self._a = a
        self._b = b

    def __str__(self):
        return "An instance of class Test with state: a=%s b=%s" % (self._a, self._b)

    def __repr__(self):
        return 'Test("%s","%s")' % (self._a, self._b)

Now, is easy to serialize instance of Test class:

x = Test('hello', 'world')
print 'Human readable: ', str(x)
print 'Object representation: ', repr(x)
print

y = eval(repr(x))
print 'Human readable: ', str(y)
print 'Object representation: ', repr(y)
print

So, running last piece of code, we'll get:

Human readable:  An instance of class Test with state: a=hello b=world
Object representation:  Test("hello","world")

Human readable:  An instance of class Test with state: a=hello b=world
Object representation:  Test("hello","world")

But, as I said in my last comment: more info is just here!

Community
  • 1
  • 1
tnotstar
  • 1,343
  • 1
  • 16
  • 26
12

You need to use __repr__. This is a standard function like __init__. For example:

class Foobar():
    """This will create Foobar type object."""

    def __init__(self):
        print "Foobar object is created."

    def __repr__(self):
        return "Type what do you want to see here."

a = Foobar()

print a
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
flow_chart
  • 155
  • 1
  • 4
  • 2
    __repr__ and __str__ have different semantics: __repr__ should be Python source that would (re-)create the same object -- this is its *repr*esentation in code ; __str__ should be a pretty userland stringification of the object. – Eric Towers Jul 12 '17 at 00:04
9

__repr__ and __str__ are already mentioned in many answers. I just want to add that if you are too lazy to add these magic functions to your class, you can use objprint. A simple decorator @add_objprint will help you add the __str__ method to your class and you can use print for the instance. Of course if you like, you can also use objprint function from the library to print any arbitrary objects in human readable format.

from objprint import add_objprint

class Position:
    def __init__(self, x, y):
        self.x = x
        self.y = y

@add_objprint
class Player:
    def __init__(self):
        self.name = "Alice"
        self.age = 18
        self.items = ["axe", "armor"]
        self.coins = {"gold": 1, "silver": 33, "bronze": 57}
        self.position = Position(3, 5)

print(Player())

The output is like

<Player
  .name = 'Alice',
  .age = 18,
  .items = ['axe', 'armor'],
  .coins = {'gold': 1, 'silver': 33, 'bronze': 57},
  .position = <Position
    .x = 3,
    .y = 5
  >
>
minker
  • 510
  • 6
  • 3
5

Even though this is an older post, there is also a very convenient method introduced in dataclasses (as of Python 3.7). Besides other special functions such as __eq__ and __hash__, it provides a __repr__ function for class attributes. You example would then be:

from dataclasses import dataclass, field
@dataclass
class Test:
    a: str = field(default="foo")
    b: str = field(default="bar")

t = Test()
print(t) 
# prints Test(a='foo', b='bar')

If you want to hide a certain attribute from being outputted, you can set the field decorator parameter repr to False:

@dataclass
class Test:
    a: str = field(default="foo")
    b: str = field(default="bar", repr=False)

t = Test()
print(t) 
# prints Test(a='foo')
dheinz
  • 988
  • 10
  • 16
2

There are already a lot of answers in this thread but none of them particularly helped me, I had to work it out myself, so I hope this one is a little more informative.

You just have to make sure you have parentheses at the end of your class, e.g:

print(class())

Here's an example of code from a project I was working on:

class Element:
    def __init__(self, name, symbol, number):
        self.name = name
        self.symbol = symbol
        self.number = number
    def __str__(self):
        return "{}: {}\nAtomic Number: {}\n".format(self.name, self.symbol, self.number

class Hydrogen(Element):
    def __init__(self):
        super().__init__(name = "Hydrogen", symbol = "H", number = "1")

To print my Hydrogen class, I used the following:

print(Hydrogen())

Please note, this will not work without the parentheses at the end of Hydrogen. They are necessary.

Hope this helps, let me know if you have anymore questions.

Stumpy
  • 37
  • 1