"Thomas Wouters" <[EMAIL PROTECTED]> wrote: > On 12/6/06, Josiah Carlson <[EMAIL PROTECTED]> wrote: > > "Thomas Wouters" <[EMAIL PROTECTED]> wrote: > > > You forget that that's actually what super() is for. It does the right > > thing > > > in the case of MI (and every other case, in fact :-) > > > > Except for this one: > > > > >>> class foo(object): > > ... pass > > ... > > >>> class bar(foo): > > ... def method(self): > > ... super(bar, self).method() > > ... > > >>> bar().method() > > Traceback (most recent call last): > > File "<stdin>", line 1, in ? > > File "<stdin>", line 3, in method > > AttributeError: 'super' object has no attribute 'method' > > >>> > > > I'm not sure what makes you say that. There is no superclass method > 'method', so 'AttributeError' seems like the Right Thing to me.
I agree with you, but it makes it *very* difficult to write properly behaving cooperative super calls. In fact, if one inherits at any point from object, one must necessarily use the following pattern in every class: try: _method = super(cls, obj).method except AttributeError: pass else: result = _method(...) How is this reasonable or from an "I want to write correct code" standpoint? I would argue that it isn't reasonable, and is in fact insane. I don't want to write that, but to prevent AttributeErrors from cropping up in arbitrary locations, it is necessary. > > Because of this kind of thing, I do my best to never produce code that > > has a diamond inheritance structure (except for object), and always use > > things like foo.method(self). > > > Which would have given you the same AttributeError. No it wouldn't have, because I wouldn't have written foo.method(self) bar.method(). I was using it as an example of class.method(self) calling semantics. I am ([un]fortunately) anal-retentive enough to pre-check my calls. > If you want co-operative MI classes, you need to do more than just use > super(): you need a baseclass that provides the 'interface', if you will, > that you wish to co-operate in. For many of the standard __hooks__, object Certainly that is a solution, but it kills one of the major uses of multiple inheritance: mixins. Not all mixin classes subclass from the *one and only one base class that doesn't call super*. An example of such is in the standard library; SocketServer and its derivatives (or whatever it is, I can never remember). I think about the only thing in common is perhaps their subclassing of object. > Avoiding MI is certainly a good option, provided you're able to enforce that > policy somehow. Actually, I use MI quite often, I just verify that I never have a diamond inheritance with anything other than object. For example: class A(X): pass class B(A): pass class C(A): pass class D(B, C): pass I never do the above unless I *know* that X is object, because then I *know* that in D.meth(self) I can use B.meth(self) and C.meth(self) (assuming that D, B, and C all implement a .meth() method). But again, I find that being anal-retentive is easier and faster than fighting with super() and its semantics. - Josiah _______________________________________________ Python-3000 mailing list Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com