Python provides a class attribute __mro__ for
each type, and a type called super. The
__mro__ attribute is a tuple containing the type
itself and all of its supertypes in a specific order. The type
super is used in place of the
find_out_whos_next() method but is capable of more.
Example 2.5. One super technique
class B(A):def do_your_stuff(self): super(B, self).do_your_stuff()
# do stuff with self for B
If we're using a class method, we don't have an instance to call
super with. Fortunately for us,
super works even with a type as the second
argument. Observe that above, super uses
self only to get at
self.__class__. The type can be passed directly to
super as shown below.
Example 2.6. Using super with a class method
class B(A):
def do_something(cls):
super(B, cls).do_something()
do_something = classmethod(do_something)
There is a different way to use super as well.
Example 2.7. Another super technique
class B(A):
def do_your_stuff(self):
self.__super.do_your_stuff()
# do stuff with self for B
B._B__super = super(B)
When created with only a type, the super instance
behaves like a descriptor. This means (if d is an
instance of D) that
super(B).__get__(d) returns the same thing as
super(B,d). In
above, we munge an
attribute name, similar to what Python does for names starting with
double underscore inside the class. So this is
accessible as self.__super within the body of the
class. If we didn't use a class specific attribute name, accessing the
attribute through the instance self might return an
object defined in a subtype.
While using super we typically use only one
super call in one method even if the class has
multiple bases. Also, it is a good programming practice to use
super instead of calling methods directly on a base
class.
A possible pitfall appears if do_your_stuff()
accepts different arguments for C and
A. This is because, if we use
super in B to call
do_your_stuff() on the next
class, we don't know if it is going to be called on
A or C. If this scenario is
unavoidable, a case specific solution might be required.
# do stuff with self for B