On Tue, Feb 17, 2015 at 12:47 AM, Mario Figueiredo <mar...@gmail.com> wrote: > The following is quoted from Learning Python, 5th Edition: > >>Java programmers may especially be interested to know that Python also has a >>super >>built-in function that allows calling back to a superclass’s methods more >>generically— >>but it’s cumbersome to use in 2.X; differs in form between 2.X and 3.X; >>relies on unusual >>semantics in 3.X; works unevenly with Python’s operator overloading; and does >>not >>always mesh well with traditionally coded multiple inheritance, where a >>single superclass call won’t suffice. >> >>In its defense, the supercall has a valid use case too—cooperative >>same-named method >>dispatch in multiple inheritance trees—but it relies on the “MRO” ordering of >>classes, >>which many find esoteric and artificial; unrealistically assumes universal >>deployment >>to be used reliably; does not fully support method replacement and varying >>argument >>lists; and to many observers seems an obscure solution to a use case that is >>rare in real >>Python code. >>
Let's take a step back here. super() depends on the "MRO" ordering of classes. Yes, but that's not super()'s decision - that is, quite fundamentally, how Python classes work. Here's a quick look at the MRO; this should work equally in Py2 and Py3: class Top(object): def foo(self): print("I am top - foo") def top(self): print("I am top - top") class Left(Top): def foo(self): print("I am left - foo") super(Left, self).foo() def leftright(self): print("I am left - leftright") class Right(Top): def foo(self): print("I am right - foo") super(Right, self).foo() def leftright(self): print("I am right - leftright") class Diamond1(Left, Right): def foo(self): print("I am diamond1 - foo") super(Diamond1, self).foo() # No leftright method class Diamond2(Left, Right): def foo(self): print("I am diamond2 - foo") super(Diamond2, self).foo() def leftright(self): print("I am diamond2 - leftright") super(Diamond2, self).leftright() print(Diamond1.__mro__) print(Diamond2.__mro__) d1 = Diamond1() d2 = Diamond2() d1.foo() d2.foo() d1.leftright() d2.leftright() Note that calling d1.leftright() calls the method from Left, not the one from Right; and calling super() from inside Diamond2's leftright does the exact same thing. So what you have here is not "super() is weird", but "multiple inheritance is messy, and this is how Python handles it". I agree with the "cumbersome to use in 2.x", but it's not actually different in syntax across the two - correct me if I'm wrong, but I believe that if you write it out in full, your code is guaranteed to work equally in both branches. So you can't complain about the difference AND complain about the old syntax being clunky; the difference is precisely the solution to the clunkiness. "unrealistically assumes universal deployment to be used reliably". Hmm. We're talking here about a solution to diamond inheritance. Can you name *any* solution to that problem which does not require some careful management by all involved classes? In any language at all? Multiple inheritance is the issue. If you want to defer anything till a later chapter, defer that. Once you decide to learn about MI, you just have to knuckle down and learn Python's particular flavour of MI, because it's different from C++'s (both default and virtual inheritance), different from Java's ("there is no MI"), different from Pike's, etc. And when you learn Python's MI, what you'll be learning is the MRO; super() just comes along for the ride. Explicit naming of superclasses is fragile for several reasons. Firstly, it breaks the parallel between "method which calls its superclass method" and "absence of method, and implicit referral to superclass" (as the latter guarantees to use the MRO); and secondly, you end up writing your superclass name a lot of times. Though, to be honest, the Py2 super() syntax has the same issue, just with your own class name. With the Py3 shorthand syntax, you're not rewriting everything all over the place. ChrisA -- https://mail.python.org/mailman/listinfo/python-list