I mostly agree with what Ben says, comments below. On Wed, Jul 01, 2015 at 12:48:47PM +1000, Ben Finney wrote: > Alan Gauld <alan.ga...@btinternet.com> writes: > > > Whilst I agree with the general use of super I'm not sure what > > the MRO resolution has to do with this case? > > When accessing the superclass, the MRO is always relevant.
For those who aren't sure, MRO is "Method Resolution Order". To be precise, all (new style) classes have a MRO: py> object.__mro__ (<type 'object'>,) In the multiple-inheritance world, all inheritance is supposed to follow the MRO, at least by default. It should be quite unusual to manually bypass the MRO or invent your own, that should stand out as a code smell. One complication in Python 2 is that "classic classes" (old style classes) don't have an explicit MRO. But they do have an implicit one. Unfortunately classic classes' MRO is buggy when used with multiple inheritance with a diamond-shaped class hierachy. I won't explain that unless somebody asks, the important thing to take from this is that you should try to avoid inheriting from "classic classes" in Python 2. > > It's explicitly single inheritance and they are explicitly calling the > > superclass. > > They don't know that the superclass will be what is written there; > that's an implication of what I said with “in Python, any class an > participate in multiple inheritance”. > > The author of a class (e.g. the OP's example ‘MyList’) cannot know at > time of writing whether the superclass is ‘list’. This is because some > other class may be using ‘MyList’ in a different inheritance > arrangement. In principle, Ben is correct here, but in practice, multiple-inheritance in Python is explicitly described as *cooperative* multiple-inheritance. You cannot expect to take any two (or more) arbitrary classes and inherit from them both. Sometimes you cannot inherit from them both at all: >>> class X(list, int): ... pass ... Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: multiple bases have instance lay-out conflict Sometimes you cannot inherit from them both because there is no consistent MRO, and sometimes you cannot inherit from them both because they simply don't work well together. In this last case, Python cannot warn you about it, but your class will just not work right. ("Your save method over-writes the data my save method just wrote!" sort of thing.) The simplest way to break M-I is to directly call your parent class by name, instead of using super(). That effectively guarantees that your class cannot be used in M-I, except perhaps by accident. In a nutshell, you can physically inherit from "the" parent class by explicitly giving the name of the class, but by doing so you are effectively saying "Uh uh, oh no you don't, no way!" to any one wishing to use your class in a multiple inheritance situation. As the writer of the class, that is your right to do so (nobody can force you to write cooperative M-I classes), but in my opinion it's a bit rude or ignorant, like writing functions that never return their result but always print it instead. ("Nobody's going to re-use *my* functions, uh uh, no way!") (In the M-I world, there is no such thing as "the" parent class. There is, however, the parent *classes*.) [...] > Multiple inheitance is a fact in Python, and good practice is to not > arbitrarily write classes that break it. Hence my advice to avoid > hard-coding the superclass, and only use ‘super’ to discover the > superclass. I agree that it is good practice to use super, even if you personally expect to only use single-inheritance. You never know when somebody else, or even your future self, will decide to use M-I. Don't unnecessarily cut off that possibility, especially in Python 3 where using super() is actually easier than explicitly calling the parent class by hand: list.append(self, arg) super().append(arg) On the other hand, M-I in Python is cooperative, and it's not very often that you can expect to pick two arbitrary classes and inherit from them both. And on the third hand, inheritance in general is often over-rated, and M-I in particular is hard to get right. There's a strong argument to be made that one should only use full cooperative M-I when easier, less powerful versions like mixins and traits aren't enough. Or use composition and/or delegation instead. > So please use `super`, even in single inheritance. Otherwise you are > restricting the usefulness of your class: it can never be used with > multiple inheritance. I cannot disagree with Ben here. Even if you only intend to use single inheritance, don't unnecessarily rule out the alternatives. Using super is still usually the right thing to do. -- Steve _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor