super()
returns a descriptor, and needs two items:
- A starting point from which to search the class hierarchy.
- The argument to bind the returned methods.
For the two argument (and implicit zero-argument *) case the second argument is used to bind to, but if you do not pass in a second argument, super()
cannot invoke the descriptor protocol to bind the returned functions, classmethods, properties or other descriptors. classmethods
are still descriptors and are bound; the bind to a class and not an instance, but super()
does not know how the descriptor will use the context to which you bind.
super()
should not and cannot know that you are looking up a class method instead of a regular method; class methods only differ from regular methods because their .__get__()
method acts differently.
Why are class methods bound? Because when you subclass Foo
but do not override .hello()
, calling Bar.hello()
invokes the Foo.__dict__['hello']
function, binds it to Bar
and your first argument to hello(cls)
will be that subclass, not Foo
.
Without a second argument, super()
returns an unbound object that can manually be bound later on. You can do the binding yourself using the .__get__()
method provided by the super()
instance:
class Bar(Foo):
@classmethod
def hello(cls):
print 'hello, bar'
super(Bar).__get__(cls, None).hello()
super().__get__()
on an instance without a context effectively returns a new super()
instance with the context set. On an instance with a context .__get__()
just returns self
; it is already bound.
* In Python 3, calling super()
without arguments from inside a bound method will use the calling frame to discover, implicitly, what the type and bound object are, so you no longer have to explicitly pass in the type and object arguments in that case. Python 3 actually adds a implicit __class__
closure variable to methods for this purpose. See PEP 3135 and Why is Python 3.x's super() magic?