Reputation: 279
I'm trying to better understand the proper usage of the __str__
function.
Let's say I have a very simple class called Character for use in a game that looks like this:
class Character(object):
""" A game character. """
def __init__(self, name):
self.name = name
self.poisoned = False
self.strength = random.randrange(10, 20)
self.max_strength = self.strength
self.dexterity = random.randrange(10, 20)
self.max_dexterity = self.dexterity
self.hit_points = 100
self.spell_points = 100
self.weapon = []
self.spell = []
self.items = []
self.aura = []
self.xp = 0
Prior to learning about the __str__
function, I would have defined a method of the class called print_stats(self)
that would print the character stats via Character.print_stats()
. After learning about __str__
though it seemed like this was a function for defining and displaying the statistics of an object, similar to what I would do with print_stats(self)
... but in playing with it and learning that the returned value must be a string and not contain integers, it appears my assumption is wrong.
So now my question is what are some examples of good usage of the __str__
? Would the example I provide benefit from using that function?
Upvotes: 5
Views: 5317
Reputation: 310237
__str__
exists so that you can get a string representation of your object. Note that the builtin print
function/statement calls str
implicitly:
print 1
is exactly the same as:
print str(1)
which is the same as:
print (1).__str__()
because print calls __str__
implicitly.
Now to your class -- The most natural thing to do is if you would have written:
print self.foo,self.bar,self.baz
You could define __str__
as:
def __str__(self):
return " ".join(str(x) for x in (self.foo,self.bar,self.baz))
Now to print your character's stats, you'd just do:
print character #same as `print str(character)` :)
Usually this is a little limited, so there exists string formatting via .format
(or old "sprintf" style formatting using the %
operator).
def __str__(self):
return "my {foo} went to the {baz} to buy a {bar}".format(foo=self.foo,
baz=self.baz,
bar=self.bar)
Upvotes: 3
Reputation: 26160
In basic use cases, __str__()
and a method like print_stats()
can pretty safely be interchanged. However, especially for something like a character in a game, you might want to go with print_stats()
, as you won't be able to refactor __str__()
to do something like print the data to the screen (in the context of a graphical desktop or web application), or to take arguments, which could prove useful for things like this.
Upvotes: 1
Reputation: 1124858
Printing stats is a fine use of __str__()
. Simply use string formatting to return a single string value:
def __str__(self):
return ('Name: {name}\n'
'Poisoned: {poisoned}\n'
# etc.
).format(**self.__dict__)
Upvotes: 9
Reputation: 182073
The return value has to be a string, but it can be any string, including one that contains the string representation of integers. A simple example:
def __str__(self):
return "%s (strength: %i)" % (self.name, self.strength)
This might return something like "Arthur (strength: 42)"
.
Upvotes: 1
Reputation: 799450
def __str__(self):
return 'Name: %s, Hit points: %d' % (self.name, self.hit_points)
Upvotes: 1