The order of super
arguments reflects Python's idea of unbound and bound methods/descriptors. In short, the second argument is optional and thus must come after the required first argument.
[...]
If the second argument is omitted, the super object returned is unbound. If the second argument is an object, isinstance(obj, type) must be true. If the second argument is a type, issubclass(type2, type) must be true (this is useful for classmethods).
This reflects how a method call self.method()
is equivalent to Class.method(self)
, i.e. the order of operands is Class
then self
.*
Python methods/descriptors come in two flavours: unbound on their defining class, and bound on their instance.*
>>> class Base:
... def method(self): print('called Base method')
...
>>> Base.method # unbound method
<function __main__.Base.method(self)>
>>> Base().method # bound method
<bound method Base.method of <__main__.Base object at 0x10dd0e910>>
>>> Base().method()
called Base method
A bound descriptor is created by taking an unbound descriptor and binding it to an instance. This is encoded and implemented in the descriptor protocol.
>>> instance = Base()
>>> unbound = Base.method
>>> unbound.__get__(instance)
<bound method Base.method of <__main__.Base object at 0x10dd14510>>
>>> unbound.__get__(instance)()
called Base method
The super
type is by default unbound. Binding it via the descriptor protocol or by passing an instance is equivalent.
>>> class Child(Base): ...
>>> instance = Child()
>>> super(Child, instance)
<super: __main__.Child, <__main__.Child at 0x10dcda9d0>>
>>> super(Child).__get__(instance)
<super: __main__.Child, <__main__.Child at 0x10dcda9d0>>
In either case, the class must be passed first before the instance.
From the python-dev archive:
Add 'super', another new object type with magical properties.
super(type) -> unbound super object
super(type, obj) -> bound super object; requires isinstance(obj, type)
Typical use to call a cooperative superclass method:
class C(B):
def meth(self, arg):
super(C, self).meth(arg);
*
This description glosses over the finer details of the descriptor protocol. For example, a method/descriptor can be bound to a class as well.