Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between super().__repr__() and repr(super())?

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)
>>> 
like image 381
Camion Avatar asked Nov 24 '18 01:11

Camion


People also ask

What is the __ repr __ method in Python?

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.

What is the purpose of defining the functions __ str __ and __ repr __ within a class how are the two functions different?

__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.

What does super () do in Python?

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.

What is super () __ Init__ in Python?

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.


2 Answers

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).

like image 198
ShadowRanger Avatar answered Sep 18 '22 10:09

ShadowRanger


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]
like image 35
juanpa.arrivillaga Avatar answered Sep 18 '22 10:09

juanpa.arrivillaga