whytheq
whytheq

Reputation: 35557

Difference between __str__(self) and show(self)

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

Answers (3)

John La Rooy
John La Rooy

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

HennyH
HennyH

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

Anton Egorov
Anton Egorov

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

Related Questions