You should always use super()
I've done it (and now I'm embarrassed by
that). I've seen other people do it by accident
(to pick something I was recently looking at). And yes, I know,
using super()
is kind of annoying (Python 3
makes it much nicer). But still: you should always use super()
instead of directly calling up to your parent class.
(It's mostly a coincidence that both examples I gave here are metaclasses, except that a metaclass is one of the few cases in Python where you have to call up to a built-in type.)
It may not be obvious to people what problems not using super()
causes, so I'll give an example in the traditional illustrated
form:
class Meta1(type): def __new__(meta, name, bases, odict): print "meta1 new" return type(name, bases, odict) class Meta2(type): def __new__(meta, name, bases, odict): print "meta2 new" return type(name, bases, odict) class Joined(Meta1, Meta2): pass class Testing(object): __metaclass__ = Joined def frotz(self): print "frotzing", self
Imagine that you have two metaclasses, each of which does something
useful to your class. You want to combine them, getting both effects,
so you create the Joined
metaclass to multi-inherit from them. But
when you try it you discover that despite the multi-inheritance, only
one of them is actually taking effect; in this example, you'll only
see 'meta1 new
' printed when you want to see both that and 'meta2
new
'. Consistently using super()
avoids this problem and makes sure
that all metaclasses get invoked (in what is considered the right order).
A similar situation happens any time more than one class is modifying
a single method.
(Metaclasses are especially prone to this because they're one of the cases where several classes commonly need to modify the exact same method. Many other cases of multiple inheritance and mixin classes have the additional classes overriding disjoint methods.)
The need for super()
is interesting partly because it's one of the few
places where a Python class can easily close itself to later outside
modification. Python classes are in general famously 'open'; outside
people can reach into them to change things, forcefully subclass
them, and otherwise do things that the original
class might object to (and that other languages allow the original
class to prevent). But a class that fails to use super()
(whether
through neglect or deliberate choice) can't be safely used in a multiple
inheritance situation; you can't use it as a mixin or mix other things
in with it. And it's not something that is at all easily fixed from
outside, since you can't just straightforwardly subclass the class and
replace the particular errant method.
(If you have a single non-super()
-using class, you can
sometimes manage to manipulate the method resolution order so that the 'bad' class is the last class and so
things work. Among other things, this is quite fragile.)
|
|