Prev: Builtn super() function. How to use it with multiple inheritance? And why should I use it at all?
Next: Multiple versions of Python coexisting in the same OS
From: Steven D'Aprano on 24 Jul 2010 23:48 On Sun, 25 Jul 2010 13:58:00 +1200, Gregory Ewing wrote: > Lacrima wrote: > >> But what if SuperClass1 is from third party library? > > If it hasn't been designed for super(), then you can't use super() with > it. > > super() only works when *every* class in the hierarchy has been designed > with it in mind. That incorrect. You can certainly use super() with classic classes in the hierarchy, and super() didn't even exist when they were created. >>> class Parent: .... def method(self, arg): .... return repr(arg) .... >>> class Classic(Parent): .... def method(self, arg): .... return "argument was %s" % Parent.method(self, arg) .... >>> class New(object, Classic): .... def method(self, arg): .... return super(New, self).method(arg).upper() .... >>> x = New() >>> x.method('spam') "ARGUMENT WAS 'SPAM'" The problem isn't super(), and people who give glib advise "don't use super()" are just compounding the problem. The problem is with multiple inheritance where methods have different method signatures. If you don't change the method signatures, super() will work fine. Advising people not to use super() might make people feel virtuous, but it doesn't do anything to help the reader write non-buggy MI hierarchies. It pushes the effort of dealing with multiple inheritance onto them, forcing them to re-implement the MRO, probably badly. Can you re- implement the C3 algorithm? Have you even heard of it? If you answer No to either of those questions, chances are high that trying to deal with the MRO manually will lead to worse bugs than using super(). Should you use super()? 1. If you're doing multiple inheritance with metaclasses, you MUST use super(). 2. If you're using single inheritance only, and never modify method signatures, there is no reason not to use super(). 3. If you're using mixins, you should use super(). 4. If you never modify method signatures, then you should use super(). 5. If you do modify method signatures, you shouldn't do that (except possibly in constructors, and even there only cautiously). But if you do it anyway, then you should use super() *except* in the methods where you modify the signature. 6. If you don't use super(), chances are that your class hierarchy is still buggy, but instead of failing loudly and noisily with an exception, it's silently giving the wrong results. 7. If you can avoid multiple inheritance in favour of another technique (such as composition), you should strongly consider that. -- Steven |