How to print instances of a class using print()?

1,067,643

Solution 1

>>> 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.

Solution 2

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)}>"

Solution 3

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}

Solution 4

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.

Solution 5

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__)))
Share:
1,067,643
Markus Joschko
Author by

Markus Joschko

I work with GPUs on deep learning and computer vision.

Updated on July 08, 2022

Comments

  • Markus Joschko
    Markus Joschko almost 2 years

    I am learning the ropes in Python. When I try to print an object of class Foobar using the print() function, I get an output like this:

    <__main__.Foobar instance at 0x7ff2a18c>
    

    Is there a way I can set the printing behaviour (or the string representation) of a class and its objects? For instance, when I call print() on a class object, I would like to print its data members in a certain format. How to achieve this in Python?

    If you are familiar with C++ classes, the above can be achieved for the standard ostream by adding a friend ostream& operator << (ostream&, const Foobar&) method for the class.

  • visual_learner
    visual_learner over 14 years
    +1 but your class code's __str__ is different from the interactive shell's results you give. :P
  • dbr
    dbr over 14 years
    Err, oops.. manually modifying REPL output never ends well. I should probably doctest my posts :P
  • kender
    kender over 14 years
    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...)
  • visual_learner
    visual_learner over 14 years
    @kender - I didn't know about it, but in retrospect it makes perfect sense given Python 2.x's broken Unicode handling.
  • Markus Joschko
    Markus Joschko over 14 years
    Thanks. But, the string formatting type (%) in your example is deprecated. Could you change to the str.format() type? :-)
  • dbr
    dbr over 14 years
    The % string formatting isn't deprecated, from docs.python.org/whatsnew/2.6.html "the % operator is supplemented by a more powerful string formatting method, format()"
  • Markus Joschko
    Markus Joschko over 14 years
    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."
  • Janusz Lenar
    Janusz Lenar over 12 years
    Pitty, %'s been very convenient.
  • tnotstar
    tnotstar over 11 years
    I think this answer cannot be completed without a link to this other one!
  • Viet
    Viet almost 11 years
    Saved me! However, after re-implementing the method __repr__(self), print will mislead users. Are you aware of any best practices around this?
  • Janac Meena
    Janac Meena almost 8 years
    To Java programmers: __str__(self) is like the toString() of the python world
  • Eric Towers
    Eric Towers almost 7 years
    repr and str have different semantics: repr should be Python source that would (re-)create the same object -- this is its representation in code ; str should be a pretty userland stringification of the object.
  • Hendy Irawan
    Hendy Irawan over 6 years
    This won't work if the object is inside another data structure, try: print([Test(123)])
  • Sajuuk
    Sajuuk over 6 years
    looks like this is not the case in python3.6 at least to what I'm using
  • geoidesic
    geoidesic about 6 years
    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?
  • pranaygoyal02
    pranaygoyal02 over 5 years
    Would you know how to know if the dict key has objects in its values?
  • John
    John over 5 years
    @HadoopEvangelist Are you asking how to recursively print those objects as well or just determine if there are objects?
  • Mohseen Mulla
    Mohseen Mulla over 3 years
    This is one of the best answers out there when it comes to a quick debug. Thanks @John
  • SleepyBoBos
    SleepyBoBos over 3 years
    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
  • sancho.s ReinstateMonicaCellio
    sancho.s ReinstateMonicaCellio over 2 years
    Essentially the same as stackoverflow.com/a/32635523/2707864
  • kenyee
    kenyee over 2 years
    this looks funky when values have spaces...
  • NeronLeVelu
    NeronLeVelu about 2 years
    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.