Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python super() arguments: why not super(obj)?

I am trying to understand when and how to use super() in Python correctly (either 2.7.x or 3.x)

on >>> help(super) the interpreter tells me how to call it:

class super(object)  |  super(type) -> unbound super object  |  super(type, obj) -> bound super object; requires isinstance(obj, type)  |  super(type, type2) -> bound super object; requires issubclass(type2, type) 

I understand that in Python3.x it's now possible to juse use super() within a class definition, but I don't understand why super(obj) is not possible. Or super(self) within a class definition.

I know there must be a reason for it, but I can't find it. To me those lines are equivalent to super(obj.__class__, obj) or super(self.__class__, self) and those would work right?

I would think that just typing super(obj) would be a nice shortcut even in Python 3.x.

like image 744
Gabriel Avatar asked Jul 07 '13 06:07

Gabriel


People also ask

Can we pass arguments to super () in Python?

A super() Deep Dive While the examples above (and below) call super() without any parameters, super() can also take two parameters: the first is the subclass, and the second parameter is an object that is an instance of that subclass.

What arguments does super take Python?

The super() method does not accept any arguments. You specify the method you want to inherit after the super() method. The above Cheese Python class inherits the values from the Food class __init__() method. We call the super() class method to inherit values from the Food class.

How does super () work in Python?

The super() function in Python makes class inheritance more manageable and extensible. The function returns a temporary object that allows reference to a parent class by the keyword super. The super() function has two major use cases: To avoid the usage of the super (parent) class explicitly.

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.


1 Answers

The two-argument form is only needed in Python 2. The reason is that self.__class__ always refers to the "leaf" class in the inheritance tree -- that is, the most specific class of the object -- but when you call super you need to tell it which implementation is currently being invoked, so it can invoke the next one in the inheritance tree.

Suppose you have:

class A(object):    def foo(self):       pass  class B(A):    def foo(self):       super(self.__class__, self).foo()  class C(B):    def foo(self):       super(self.__class__, self).foo()  c = C() 

Note that c.__class__ is C, always. Now think about what happens if you call c.foo().

When you call super(self.__class__, self) in a method of C, it will be like calling super(C, self), which means "call the version of this method inherited by C". That will call B.foo, which is fine. But when you call super(self.__class__, self) from B, it's still like calling super(C, self), because it's the same self, so self.__class__ is still C. The result is that the call in B will again call B.foo and an infinite recursion occurs.

Of course, what you really want is to be able to call super(classThatDefinedTheImplementationThatIsCurrentlyExecuting, self), and that is effectively what the Python 3 super() does.

In Python 3, you can just do super().foo() and it does the right thing. It's not clear to me what you mean about super(self) being a shortcut. In Python 2, it doesn't work for the reason I described above. In Python 3, it would be a "longcut" because you can just use plain super() instead.

The super(type) and super(type1, type2) uses might still be needed occasionally in Python 3, but those were always more esoteric usages for unusual situations.

like image 144
BrenBarn Avatar answered Sep 20 '22 17:09

BrenBarn