I'm experimenting with OOP python and I wasn't sure about the __repr__
function inheritance. Since the parent class function looked like this:
def __repr__(self):
'''Returns representation of the object'''
return("{}({!r})".format("Class name", self._param))
I wanted to know if it is better to use a generic approach (which could be suitable for children classes as well) like the following one:
def __repr__(self):
'''Returns representation of the object'''
return("{}({!r})".format(self.__class__.__name__, self._param))
or if it is a good practice to override the function in every class.
Also, please ignore the encoding part, since I'm leaving it behind.
Well the __repr__
has a special meaning in Pythons data model:
object.__repr__(self)
Called by the repr()
built-in function to compute the “official” string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form <...some useful description...>
should be returned. The return value must be a string object. If a class defines __repr__()
but not __str__()
, then __repr__()
is also used when an “informal” string representation of instances of that class is required.
This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.
That means the string that is returned by __repr__
should be usable to create another object just like it. So __repr__
is something that quite often needs overriding, not because of the __class__.__name__
but because the "state" has to be captured in the representation.
class A(object):
def __init__(self, param):
self._param = param
def __repr__(self):
'''Returns representation of the object'''
return("{}({!r})".format(self.__class__.__name__, self._param))
Then you absolutely should override the __repr__
when you add parameters for __init__
:
class B(A):
def __init__(self, param1, param2):
self._param = param1
self._param2 = param2
def __repr__(self):
'''Returns representation of the object'''
return("{}({!r})".format(self.__class__.__name__, self._param, self._param2))
But in case the __repr__
of the superclass still accurately "describes" the subclass then there's no point overloading the __repr__
:
class B(A):
pass
However it's always a good choice to use self.__class__.__name__
over hard-coding the class name, just in case you or someone else subclasses it.
Yes - - it is not just "ok", but it is what is more practical in almost every project and class hierarchy.
Actually, this is almost a perfect "text book example" of when to use class inheritance, and just let the code in the superclasses be reused.