On Jan 5, 2005, at 1:23 PM, Guido van Rossum wrote: >> The issue of mixing super() and explicit calls to the superclass's >> method occur with any method. (Thus making it difficult/impossible for >> a framework to convert to using super without breaking client code >> that >> subclasses). > > Well, client classes which are leaves of the class tree can still > safely use BaseClass.thisMethod(self, args) -- it's only classes that > are written to be extended that must all be converted to using > super(). So I'm not sure how you think your clients are breaking. See the section "Subclasses must use super if their superclasses do". This is particularly a big issue with __init__. >> Adding optional arguments to one branch of the inheritance tree, but >> not another, or adding different optional args in both branches. >> (breaks unless you always pass optional args as keywordargs, and all >> methods take **kwargs and pass that on to super). > > But that breaks anyway; I don't see how using the old > Base.method(self, args) approach makes this easier, *unless* you are > using single inheritance. If you're expecting single inheritance > anyway, why bother with super()? There is a distinction between simple multiple inheritance, which did work in the old system vs. multiple inheritance in a diamond structure which did not work in the old system. However, consider something like the following (ignore the Interface/implements bit if you want. It's just to point out a common situation where two classes can independently implement the same method without having a common superclass): class IFrob(Interface): def frob(): """Frob the knob""" class A: implements(IFrob) def frob(self, foo=False): print "A.frob(foo=%r)"%foo class B: implements(IFrob) def frob(self, bar=False): print "B.frob(bar=%r)"%bar class C(A,B): def m(self, foo=False, bar=False): A.m(self, foo=foo) B.m(self, bar=bar) print "C.frob(foo=%r, bar=%r)"%(foo,bar) Now, how do you write that to use super? Here's what I come up with: class IFrob(Interface): def frob(): """Frob the knob""" class A(object): implements(IFrob) def frob(self, foo=False, *args, **kwargs): try: f = super(A, self).frob except AttributeError: pass else: f(foo=foo, *args, **kwargs) print "A.frob(foo=%r)"%foo class B(object): implements(IFrob) def frob(self, bar=False, *args, **kwargs): try: f = super(B, self).frob except AttributeError: pass else: f(bar=bar, *args, **kwargs) print "B.frob(bar=%r)"%bar class C(A,B): def frob(self, foo=False, bar=False, *args, **kwargs): super(C, self).frob(foo, bar, *args, **kwargs) print "C.frob(foo=%r, bar=%r)"%(foo,bar) > And using multiple inheritance the old was was not confusing? Surely > you are joking. It was pretty simple until you start having diamond structures. Then it's complicated. Now, don't get me wrong, I think that MRO-calculating mechanism really is "the right thing", in the abstract. I just think the way it works out as implemented in python is really confusing and it's easy to be worse off with it than without it. > If they're happy with single inheritance, let them use super() > incorrectly. It works, and that's what count. Their code didn't work > right with multiple inheritance before, it still doesn't. Some people > just are uncomfortable with calling Base.method(self, ...) and feel > super is "more correct". Let them. Their code worked right in M-I without diamonds before. Now it likely doesn't work in M-I at all. James
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4