Reputation: 35557
Just encountered an example Fraction class and am not too sure what the difference between these two methods is. Once __str__
has been implemented doesn't show
become redundent ?
def __str__(self):
return str(self.num)+"/"+str(self.den)
def show(self):
print(self.num,"/",self.den)
I realise __str__
is a magic method who's implementation takes care of any context that requires a string version of the class. Just can't see the point of the show(self)
method ?
EDIT
Is show a generic method that most classes require?
My problem is if I have a fraction x then all I need do is print(x)
and I will see 1\2
or what ever the instance holds - so why would one ever bother implementing an additional method show
?
Upvotes: 3
Views: 7951
Reputation: 304137
The __str__
method is being very careful to make sure everything is a str
and so it returns a str
.
The show
method is relying on print to convert self.num
and self.den
to str implicitly. It displays the result as a side-effect, and returns None
print
will insert a space between each parameter.
>>> str(3)+"/"+str(5)
'3/5'
>>> print(3,"/",5)
3 / 5
If you don't care about the extra spaces, there's really no reason not to use
def show(self):
print(self)
perhaps the author thinks it's clearer not to do it that way.
Decoupling show
and __str__
this way may also be surprising when you try to make a subclass. If the subclass overrides __str__
, you would probably expect the change to be reflected in show
too.
Upvotes: 4
Reputation: 7944
The purpose of having a __str__
method is to create a string representation of the object. __str__
should return a string. If the implementation of __str__
instead printed the string representation and returned nothing, when the object was used in a string context a TypeError
will be raised. Take for example:
def __str__(self):
print '%f/%f'%(self.num,self.den)
If we went to display a fraction object like so:
f = Fraction(1,2)
print f
we get an exception:
Traceback (most recent call last):
File "/Users/.../Desktop/...", line 13, in <module>
print f
TypeError: __str__ returned non-string (type NoneType)
>>>
This is because __str__
is used to get the string representation of the object, not print it (by convention that is, you could print as long as you return a string). That's what the print
statment/function is used for in conjunction with a __str__
method.
On the other hand a method like show
:
def show(self):
print(self.num,"/",self.den) #or even print(self) (for the last part of answer)
Is essentially equivalent to print(f)
in the above case (except it includes spaces next to the operands). show
is used to output the string representation, while __str__
to get the representation.
However, additional logic may be added to show
which isn't appropriate/necessary when constructing a string representation, and hence make sense to have both methods.
You can however use a method like show
where a print
statement is inappropriate i.e:
if f.show(): pass
if print(f): pass #raise exception
Upvotes: 8
Reputation: 1194
__str__
is a magic method that will be called each time object will be treated as string, for example str(fraction_instance)
Upvotes: 3