I\'ve noticed that when an instance with an overloaded __str__
method is passed to the print
function as an argument, it prints as intended. Howeve
I'm not sure why exactly the __str__
method of a list returns the __repr__
of the objects contained within - so I looked it up: [Python-3000] PEP: str(container) should call str(item), not repr(item)
Arguments for it:
-- containers refuse to guess what the user wants to see on str(container) - surroundings, delimiters, and so on;
-- repr(item) usually displays type information - apostrophes around strings, class names, etc.
So it's more clear about what exactly is in the list (since the object's string representation could have commas, etc.). The behavior is not going away, per Guido "BDFL" van Rossum:
Let me just save everyone a lot of time and say that I'm opposed to this change, and that I believe that it would cause way too much disturbance to be accepted this close to beta.
Now, there are two ways to resolve this issue for your code.
The first is to subclass list
and implement your own __str__
method.
class StrList(list):
def __str__(self):
string = "["
for index, item in enumerate(self):
string += str(item)
if index != len(self)-1:
string += ", "
return string + "]"
class myClass(object):
def __str__(self):
return "myClass"
def __repr__(self):
return object.__repr__(self)
And now to test it:
>>> objects = [myClass() for _ in xrange(10)]
>>> print objects
[<__main__.myClass object at 0x02880DB0>, #...
>>> objects = StrList(objects)
>>> print objects
[myClass, myClass, myClass #...
>>> import random
>>> sample = random.sample(objects, 4)
>>> print sample
[<__main__.myClass object at 0x02880F10>, ...
I personally think this is a terrible idea. Some functions - such as random.sample
, as demonstrated - actually return list
objects - even if you sub-classed lists. So if you take this route there may be a lot of result = strList(function(mylist))
calls, which could be inefficient. It's also a bad idea because then you'll probably have half of your code using regular list
objects since you don't print them and the other half using strList
objects, which can lead to your code getting messier and more confusing. Still, the option is there, and this is the only way to get the print
function (or statement, for 2.x) to behave the way you want it to.
The other solution is just to write your own function strList()
which returns the string the way you want it:
def strList(theList):
string = "["
for index, item in enumerate(theList):
string += str(item)
if index != len(theList)-1:
string += ", "
return string + "]"
>>> mylist = [myClass() for _ in xrange(10)]
>>> print strList(mylist)
[myClass, myClass, myClass #...
Both solutions require that you refactor existing code, unfortunately - but the behavior of str(container)
is here to stay.