python - readable list of objects - python

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)

Related

Python:Retain memory address of object after __str__ method has been implemented

How can I retain the address of object after I implemented str method on a class
class X:
pass
x=X()
print(x)
#<__main__.X object at 0x000000A63773C5B0>hexadecimal value here I want to be able to bind to some variable
class X:
def __str__(self):
objinfo='X object is located at {}'.format(argument here I wish to be hexadecimal value produced before __str__ method is implemented on a class)
return objinfo
Thanks in advance
I think that id(object) gives you the address of an object, converts it to hexadecimal with hex().
class X():
def __init__(self,x):
self.x = x
def __str__(self):
objinfo='X object is located at {}'.format(hex(id(self)))
return objinfo
Before showing the answer, I'm really not sure if this works, but I'm pretty sure it does !
class X:
def __str__(self):
return hex(id(self)).upper()
x = X()
print(x)
Here, "id" function, return a unique number, for that precise object."hex" function, simply transform it in hexadecimal !
I'm pretty suree it gives the adress !

Return object name instead of its memory address [duplicate]

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)

Set name of object in class

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)

Python: how to recursively apply __str__ in print

I had some problem printing user-defined class instance in containers. In short, if my code is:
class A():
def __str__(self):
return 'abc'
class B():
def __str__(self):
return str(A())
a,b=A(),B()
C=[[a],b]
print(C)
Then the output should be like:[[<__main__.A object at 0x02D99910>], <__main__.B object at 0x02DD5030>], but I want it to recursively apply customized __str__ and works even in nested lists or classes, i.e. I want the output to be [['abc'],'abc']. Any pythonic way to do?
#Blckknight should have submitted as an answer, because that seems to be the correct answer (it worked for my very similar question):
**override repr() instead of str()
def __repr__(self):
return "abc"
you can also add this for completeness
def str(self):
return self.repr()
#Blckknight if you want to resubmit as an answer for the points, you should. I wish I could just add a comment but i don't have the reputation to do that.
You would need to override the __str__ method of list, not A or B, since that's where the recursion needs to begin. That is, to turn a list into a string, you need to recursively turn each object in the list into a string. Unfortunately, you cannot do that. The best you can do is write a separate function, something like
def list_to_str(l):
if isinstance(l, list):
return "[%s]" % (", ".join(map(list_to_str, l)),)
else:
return "'%s'" % (str(l),)
print(list_to_str(C))

Convention to print an object in python

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

Categories