Is there any standard convention to print an object in python. I know that if I just try to print the object it would print the memory address but I would like to overwrite that method and be able to print human readable format of the object to help in debugging.
is there any standard convention people follow or is it not a good way to define such a method instead there are better alternatives?
You can overwrite either the __str__ or the __repr__ method.
There is no convention on how to implement the __str__ method; it can just return any human-readable string representation you want. There is, however, a convention on how to implement the __repr__ method: it should return a string representation of the object so that the object could be recreated from that representation (if possible), i.e. eval(repr(obj)) == obj.
Assuming you have a class Point, __str__ and __repr__ could be implemented like this:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return "(%.2f, %.2f)" % (self.x, self.y)
def __repr__(self):
return "Point(x=%r, y=%r)" % (self.x, self.y)
def __eq__(self, other):
return isinstance(other, Point) and self.x == other.x and self.y == other.y
Example:
>>> p = Point(0.1234, 5.6789)
>>> str(p)
'(0.12, 5.68)'
>>> "The point is %s" % p # this will call str
'The point is (0.12, 5.68)'
>>> repr(p)
'Point(x=0.1234, y=5.6789)'
>>> p # echoing p in the interactive shell calls repr internally
Point(x=0.1234, y=5.6789)
>>> eval(repr(p)) # this echos the repr of the new point created by eval
Point(x=0.1234, y=5.6789)
>>> type(eval(repr(p)))
<class '__main__.Point'>
>>> eval(repr(p)) == p
True
Implement function __str__ in the class for the object you are printing.
If you are printing objects for a class that you can't alter then it is fairly straightforward to provide your own print function, since you are using Python 3.
Edit: Usually the string returned by __str__ will be specific to the class, but will at least be enough to identify the object. The exact format of the string will vary depending on the class and public attributes.
Edit2: Here is a simple (cutdown) example from a class describing countries:
def __str__(self):
return "{0:<32} {1:>010}".
format(self.__name, self.__population)
If your object can be represented in a way that allows recreation, then override the __repr__ function. For example, if you can create your object with the following code:
MyObject('foo', 45)
The the __repr__ should return "MyObject('foo', 45)". You then don't need to implement a __str__.
But if the object is so complex that you can't represent it like that, override __str__ instead. You should then return something that both makes it clear the object can't be recreated, and that it is an object. Hence, don't return "foo:45", because that looks like a string, or {'foo': 45} because that looks like a dictionary, and that will confuse you when you debug.
I'd recommend that you keep the brackets, for example <MyObject foo:45>. That way it is clear that you have been printing an object, and it is also clear that it is not just a question of writing MyObject('foo', 45) to recreate the object, but that there is more data stored.
The standard way to print custom info about an object (class instance) is to use __str__ method:
class A:
var = 1
def __str__(self):
return 'Accessing from print function, var = {0}'.format(self.var)
In this method you can display any info you want
a = A()
print(a)
>>> Accessing from print function, var = 1
Related
This question already has answers here:
How to make print call the __str__ method of Python objects inside a list?
(8 answers)
Closed 4 years ago.
Coming from a Java background, I understand that __str__ is something like a Python version of toString (while I do realize that Python is the older language).
So, I have defined a little class along with an __str__ method as follows:
class Node:
def __init__(self, id):
self.id = id
self.neighbours = []
self.distance = 0
def __str__(self):
return str(self.id)
I then create a few instances of it:
uno = Node(1)
due = Node(2)
tri = Node(3)
qua = Node(4)
Now, the expected behaviour when trying to print one of these objects is that it's associated value gets printed. This also happens.
print uno
yields
1
But when I do the following:
uno.neighbours.append([[due, 4], [tri, 5]])
and then
print uno.neighbours
I get
[[[<__main__.Node instance at 0x00000000023A6C48>, 4], [<__main__.Node instance at 0x00000000023A6D08>, 5]]]
Where I expected
[[2, 4], [3, 5]]
What am I missing? And what otherwise cringe-worthy stuff am I doing? :)
Python has two different ways to convert an object to a string: str() and repr(). Printing an object uses str(); printing a list containing an object uses str() for the list itself, but the implementation of list.__str__() calls repr() for the individual items.
So you should also overwrite __repr__(). A simple
__repr__ = __str__
at the end of the class body will do the trick.
Because of the infinite superiority of Python over Java, Python has not one, but two toString operations.
One is __str__, the other is __repr__
__str__ will return a human readable string.
__repr__ will return an internal representation.
__repr__ can be invoked on an object by calling repr(obj) or by using backticks `obj`.
When printing lists as well as other container classes, the contained elements will be printed using __repr__.
It provides human readable version of output rather "Object": Example:
class Pet(object):
def __init__(self, name, species):
self.name = name
self.species = species
def getName(self):
return self.name
def getSpecies(self):
return self.species
def Norm(self):
return "%s is a %s" % (self.name, self.species)
if __name__=='__main__':
a = Pet("jax", "human")
print a
returns
<__main__.Pet object at 0x029E2F90>
while code with "str" return something different
class Pet(object):
def __init__(self, name, species):
self.name = name
self.species = species
def getName(self):
return self.name
def getSpecies(self):
return self.species
def __str__(self):
return "%s is a %s" % (self.name, self.species)
if __name__=='__main__':
a = Pet("jax", "human")
print a
returns:
jax is a human
Answer to the question
As pointed out in another answer and as you can read in PEP 3140, str on a list calls for each item __repr__. There is not much you can do about that part.
If you implement __repr__, you will get something more descriptive, but if implemented correctly, not exactly what you expected.
Proper implementation
The fast, but wrong solution is to alias __repr__ to __str__.
__repr__ should not be set to __str__ unconditionally. __repr__ should create a representation, that should look like a valid Python expression that could be used to recreate an object with the same value. In this case, this would rather be Node(2) than 2.
A proper implementation of __repr__ makes it possible to recreate the object. In this example, it should also contain the other significant members, like neighours and distance.
An incomplete example:
class Node:
def __init__(self, id, neighbours=[], distance=0):
self.id = id
self.neighbours = neighbours
self.distance = distance
def __str__(self):
return str(self.id)
def __repr__(self):
return "Node(id={0.id}, neighbours={0.neighbours!r}, distance={0.distance})".format(self)
# in an elaborate implementation, members that have the default
# value could be left out, but this would hide some information
uno = Node(1)
due = Node(2)
tri = Node(3)
qua = Node(4)
print uno
print str(uno)
print repr(uno)
uno.neighbours.append([[due, 4], [tri, 5]])
print uno
print uno.neighbours
print repr(uno)
Note: print repr(uno) together with a proper implementation of __eq__ and __ne__ or __cmp__ would allow to recreate the object and check for equality.
Well, container objects' __str__ methods will use repr on their contents, not str. So you could use __repr__ instead of __str__, seeing as you're using an ID as the result.
__str__ is only called when a string representation is required of an object.
For example str(uno), print "%s" % uno or print uno
However, there is another magic method called __repr__ this is the representation of an object. When you don't explicitly convert the object to a string, then the representation is used.
If you do this uno.neighbors.append([[str(due),4],[str(tri),5]]) it will do what you expect.
The thing about classes, and setting unencumbered global variables equal to some value within the class, is that what your global variable stores is actually the reference to the memory location the value is actually stored.
What you're seeing in your output is indicative of this.
Where you might be able to see the value and use print without issue on the initial global variables you used because of the str method and how print works, you won't be able to do this with lists, because what is stored in the elements within that list is just a reference to the memory location of the value -- read up on aliases, if you'd like to know more.
Additionally, when using lists and losing track of what is an alias and what is not, you might find you're changing the value of the original list element, if you change it in an alias list -- because again, when you set a list element equal to a list or element within a list, the new list only stores the reference to the memory location (it doesn't actually create new memory space specific to that new variable). This is where deepcopy comes in handy!
print self.id.__str__() would work for you, although not that useful for you.
Your __str__ method will be more useful when you say want to print out a grid or struct representation as your program develops.
print self._grid.__str__()
def __str__(self):
"""
Return a string representation of the grid for debugging.
"""
grid_str = ""
for row in range(self._rows):
grid_str += str( self._grid[row] )
grid_str += '\n'
return grid_str
I want to set the name of a class to one of the variables within the class so that when I print classes I get their names, I've tried setting __name__ but it did not work.
this is my class
class SNMPData(object):
def __init__(self, device='', speed_down=0, speed_up=0, bgp_peer_state='', bgp_summary='', error=''):
self.device = device
self.speed_down = speed_down
self.speed_up = speed_up
self.bgp_peer_state = bgp_peer_state
self.bgp_summary = bgp_summary
self.error = error
self.__name__ = device
I create a list of objects then try print them
>>> list = [SNMPData(device='dev_1',speed_down=1),SNMPData(device='dev_2',speed_down=2)]
>>> print(list)
[<SNMPData object at 0x7ff052a42ef0>, <SNMPData object at 0x7ff052a42b38>]
>>>
instead of SNMPData object at 0x.... is it possible to print
['SNMPData dev_1','SNMPData dev_2']
instead?
You are looking to define __repr__ which should return a printable representation of the object. The official definition of __repr__
repr(object):
Return a string containing a printable representation of an object.
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.
bottom line is that the output from __str__ is meant to be readable by human ** whereas the output from **__repr__ is meant to be read by the Python interpreter. so when you give the string to the interpreter, it should recreate the object. Also If an object doesn't have a __str__ method then __repr__ is used instead.
Each class has a __repr__ and __str__ function which takes a single argument, self, representing the object itself. The __repr__ function returns the true string representation of the object and the __str__ function is used for str(obj) which is used for printing.
class SNMPData(object):
def __init__(self, device='', speed_down=0, speed_up=0, bgp_peer_state='', bgp_summary='', error=''):
...
def __repr__(self):
return '{} {}'.format(self.__class__.__name__, self.device)
You can do the same for __str__(self) if you want to observe this behaviour for printing.
You are able to change a text representation of your custom object by overriding __repr__ and __str__ methods:
...
def __repr__(self):
return self.__class__.__name__ + ' ' + self.device
Define __repr__(self) and __str__(self).
The former is the "official" string representation. The latter is what is returned when you cast the object to a str.
Generalizing some of the other answers, you could do:
def __str__(self):
return '{self.__class__.__name__} {self.device}'.format(self=self)
I want to set the name of a class to one of the variables within the class so that when I print classes I get their names, I've tried setting __name__ but it did not work.
this is my class
class SNMPData(object):
def __init__(self, device='', speed_down=0, speed_up=0, bgp_peer_state='', bgp_summary='', error=''):
self.device = device
self.speed_down = speed_down
self.speed_up = speed_up
self.bgp_peer_state = bgp_peer_state
self.bgp_summary = bgp_summary
self.error = error
self.__name__ = device
I create a list of objects then try print them
>>> list = [SNMPData(device='dev_1',speed_down=1),SNMPData(device='dev_2',speed_down=2)]
>>> print(list)
[<SNMPData object at 0x7ff052a42ef0>, <SNMPData object at 0x7ff052a42b38>]
>>>
instead of SNMPData object at 0x.... is it possible to print
['SNMPData dev_1','SNMPData dev_2']
instead?
You are looking to define __repr__ which should return a printable representation of the object. The official definition of __repr__
repr(object):
Return a string containing a printable representation of an object.
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.
bottom line is that the output from __str__ is meant to be readable by human ** whereas the output from **__repr__ is meant to be read by the Python interpreter. so when you give the string to the interpreter, it should recreate the object. Also If an object doesn't have a __str__ method then __repr__ is used instead.
Each class has a __repr__ and __str__ function which takes a single argument, self, representing the object itself. The __repr__ function returns the true string representation of the object and the __str__ function is used for str(obj) which is used for printing.
class SNMPData(object):
def __init__(self, device='', speed_down=0, speed_up=0, bgp_peer_state='', bgp_summary='', error=''):
...
def __repr__(self):
return '{} {}'.format(self.__class__.__name__, self.device)
You can do the same for __str__(self) if you want to observe this behaviour for printing.
You are able to change a text representation of your custom object by overriding __repr__ and __str__ methods:
...
def __repr__(self):
return self.__class__.__name__ + ' ' + self.device
Define __repr__(self) and __str__(self).
The former is the "official" string representation. The latter is what is returned when you cast the object to a str.
Generalizing some of the other answers, you could do:
def __str__(self):
return '{self.__class__.__name__} {self.device}'.format(self=self)
I have a node object that has x and y variables. I keep all of the nodes in a list called nodelist. What is the most pythonic and simple way of printing coordinates of all nodes from nodelist?
More specifically, I have a class called someclass that has
someclass.state
someclass.nodelist
I want to print its state and coordinates of the nodes in nodelist in as few as possible lines.
something like: print self.state, (i.x, i.y for i in self.nodelist)
The pythonic way to print is to use print and the pythonic way to represent an object as a string (what would be printed) is to define __str__ (note that __unicode__ is gone in python3 and is maybe not that pythonic any longer, especially when __str__ will do (ie no unicode support is needed)). Note also that the new way of formatting string is with str.format rather than using the percent operator - so I use that.
In whatever class self is of:
def __str__(self):
return "{0} {1}".format(self.state, (str(i) for i in self.nodelist))
and in whatever class self.nodelist elements are in:
def __str__(self):
return "{0}, {1}".format(self.x, self.y)
and then just print the the objects using print(obj)
This is probably a kinda commonly asked question but I could do with help on this. I have a list of class objects and I'm trying to figure out how to make it print an item from that class but rather than desplaying in the;
<__main__.evolutions instance at 0x01B8EA08>
but instead to show a selected attribute of a chosen object of the class. Can anyone help with that?
If you want to just display a particular attribute of each class instance, you can do
print([obj.attr for obj in my_list_of_objs])
Which will print out the attr attribute of each object in the list my_list_of_objs. Alternatively, you can define the __str__() method for your class, which specifies how to convert your objects into strings:
class evolutions:
def __str__(self):
# return string representation of self
print(my_list_of_objs) # each object is now printed out according to its __str__() method
You'll want to override your class's "to string" method:
class Foo:
def __str__(self):
return "String representation of me"
Checkout the __str__() and __repr__() methods.
See http://docs.python.org/reference/datamodel.html#object.__repr__
You need to override either the __str__, or __repr__ methods of your object[s]
My preference is to define a __repr__ function that can reconstruct the object (whenever possible). Unless you have a __str__ as well, both repr() and str() will call this method.
So for example
class Foo(object):
def __init__(self, a, b):
self.a = a
self.b = b
def __repr__(self):
return 'Foo(%r, %r)' % (self.a, self.b)
Doing it this way, you have a readable string version, and as a bonus it can be eval'ed to get a copy of the original object.
x = Foo(5, 1 + 1)
y = eval(str(x))
print y
-> Foo(5, 2)