On Tue, Feb 17, 2015 at 2:00 AM, Mario Figueiredo <mar...@gmail.com> wrote: > On Tue, 17 Feb 2015 01:11:01 +1100, Chris Angelico <ros...@gmail.com> > wrote: > >>So what you have here is not "super() is weird", but "multiple >>inheritance is messy, and this is how Python handles it". >> > > I'd say the diamond pattern is messy. MI is otherwise a pretty > peaceful kid without it.
In Python, everything ultimately inherits from 'object', so any MI will become a diamond. You absolutely (and correctly) expect every object, regardless of its inheritance tree, to respond to methods like __repr__; if you multiply inherit, somewhere along the way, you're going to get a __repr__ function. (Actually, with that particular example, it's probably important to override, rather than depend on the superclasses.) > I don't find the C3 linearization method particularly hard to > understand either. Contrary to Mark, I don't look at MRO as some > esoteric property of Python. Heck, took me more time to understand and > take advantage of tuple packing and unpacking, than it took me to > understand MRO. I had to get my head around the way the calls can move "across" the hierarchy, rather than simply up it. It means that "calling the superclass" might actually call a class that's completely unrelated to the one you're doing this from. In C++, calling the superclass can only ever call a parent of the current class. (Pike has a completely different model, though. Instead of calling one parent method, you can call all of them! It's very cool... as long as you know what you're doing when you make a diamond.) > What may make MRO complex is large hierarchic trees, defined across > multiple modules. But that really is complex under any method > resolution model we can think of. Precisely. It's MI that makes the complexity possible, and the MRO is one of a number of ways to tame that. > What really put me off was instead the mention to lack of support for > variadic methods and some apparent problems with operator overloading. > I reasoned that for the sake of consistency, I'm probably better using > super only when I need its specific set of features. I've no idea what he means by that, unless he's talking about methods with the same name and different argument signatures. If you have a structure like that, then any MI system is going to have problems. Possibly the best way to cope is to use **args everywhere, pop out the ones you care about, and pass the rest on. >>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); > > I agree. Super is more explicit than an explicit method call. Which is > ironic. Both in fact can coexist, with explicit method calls being > used to denote an MRO deviation, for instance. > > But frankly, I don't see the breaking of that parallel as a problem. > For the most part, you can code in complete ignorance of MRO, even in > the presence of MRI. MI name clashing is something that we ought to > avoid anyways and it is so rare we ever have to confront it, that > making a case for super on that basis is a bit weak. Sure, but I would say that the normal, default assumption should be that it's easy to do nothing. I should be able to adorn a parent method as easily as I can adorn with a function decorator. Compare: def announce(func): @wraps(func): def inner(*a,**kw): print("Calling %s!"%func.__name__) return func(*a,**kw) return inner There's a bit of boilerplate to make a pass-through decoration like that, but it's pretty straight-forward. Here's the equivalent Py3 class: class blah(...): def method(self, *a, **kw): print("Calling method on %r!"%self) return super().method(*a, **kw) If you use this model with single inheritance, you could simply name the parent class in the last line, and it'd be fine. But then you subclass this, and suddenly your adornment results in a completely different method being called - that's going to be seriously surprising. And you don't have to change anything in this class itself for the wrapper to suddenly break. ChrisA -- https://mail.python.org/mailman/listinfo/python-list