In python (3.5.2), I was expecting the repr(obj)
function to call the magic method __repr__()
of obj
's class.
However calling both of them do not seem to yield the same result. Can anyone explain why ?
Sample code :
class parent:
def __init__(self):
self.a = "haha"
def __repr__(self):
return repr(self.a)
class child(parent):
def __init__(self):
super().__init__()
self.b="bebe"
def __repr__(self):
return "("+super().__repr__()+", "+repr(super())+", "+self.b+")"
def print1(self):
print("super().__repr__() returns:", super().__repr__())
print("repr(super()) returns:", repr(super()))
print("plom(super()).__repr__() returns:", plom(super()).__repr__())
print("repr(plom(super())) returns:", repr(plom(super())))
def plom(var):
return var
t=child()
print(t.__repr__())
print(repr(t))
print('-----')
t.print1()
print('-----')
print(plom(t).__repr__())
print(repr(plom(t)))
result :
>>>
RESTART: test super.py
('haha', <super: <class 'child'>, <child object>>, bebe)
('haha', <super: <class 'child'>, <child object>>, bebe)
-----
super().__repr__() returns: 'haha'
repr(super()) returns: <super: <class 'child'>, <child object>>
plom(super()).__repr__() returns: 'haha'
repr(plom(super())) returns: <super: <class 'child'>, <child object>>
-----
('haha', <super: <class 'child'>, <child object>>, bebe)
('haha', <super: <class 'child'>, <child object>>, bebe)
>>>
Python __repr__() function returns the object representation in string format. This method is called when repr() function is invoked on the object. If possible, the string returned should be a valid Python expression that can be used to reconstruct the object again.
__str__ is used in to show a string representation of your object to be read easily by others. __repr__ is used to show a string representation of the object.
The super() function is used to give access to methods and properties of a parent or sibling class. The super() function returns an object that represents the parent class.
When you initialize a child class in Python, you can call the super(). __init__() method. This initializes the parent class object into the child class. In addition to this, you can add child-specific information to the child object as well.
Calling repr(super())
directly accesses the __repr__
on the super
class (technically, the tp_repr
of the C PyTypeObject
struct defining the super
type). Most special dunder methods behave this way when called implicitly (as opposed to explicitly calling them as methods). repr(x)
isn't equivalent to x.__repr__()
. You can think of repr
as being defined as:
def repr(obj):
return type(obj).__repr__(obj) # Call unbound function of class with instance as arg
while you were expecting it to be:
def repr(obj):
return obj.__repr__() # Call bound method of instance
This behavior is intentional; one, customizing dunder methods per-instance makes little sense, and two, prohibiting it allows for much more efficient code at the C level (it has much faster ways of doing what the illustrative methods above do).
By contrast, super().__repr__()
looks up the method on the super
instance, and super
defines a custom tp_getattro
(roughly equivalent to defining a custom __getattribute__
method), which means lookups on the instance are intercepted before they find the tp_repr
/__repr__
of the class, and instead are dispatched through the custom attribute getter (which performs the superclass delegation).
If you consult the docs, you'll see that super
returns a proxy object which delegates method calls to the appropriate class according to method resolution order.
So repr(super())
gets you the representation of the proxy object. Whereas the method call super().__repr__()
gives you the representation defined by the next class in the method resolution order.
If you want the superclass itself, try
my_object.__mro__[1]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With