Laszlo Zsolt Nagy wrote: > I tested this and I realized that if you change the parameter list in > the descendants then it is not wise to use super. > I'm going to publish the example below, I hope others can learn from it > too. > [snip and fixed formatting] > > Example (bad): > > class A(object): > def f(self): > print "A.f called" > class B(A): > def f(self,what): > super(B,self).f() > print "B.f called (%s)" % what > class C(A): > def f(self): > super(C,self).f() > print "C.f called" > class D(B,C): > def f(self): > super(D,self).f() > print "D.f called" > > d = D() > d.f() > > Will result in: > > C:/Python24/pythonw.exe -u "C:/Python/Projects/Test4/test4.py" > Traceback (most recent call last): > File "C:/Python/Projects/Test4/test4.py", line 22, in ? > d.f() > File "C:/Python/Projects/Test4/test4.py", line 17, in f > super(D,self).f() > TypeError: f() takes exactly 2 arguments (1 given)
Yeah, this problem has been discussed before. It's a restriction of super that the method signature may not change the number of parameters in this way in the inheritance hierarchy. The above is clearly a toy example. Do you really have a need for B to accept a parameter than none of the others accept? Makes it sounds like B.f might be better off as a different method. If the 'what' parameter is necessary for B.f, is it potentially applicable to the other f functions? Could you make 'what' a paramter in the other functions that defaults to, say, None? One other possible (but IMHO somewhat ugly) solution: py> class A(object): ... def f(self, *args, **kwargs): ... print 'A.f' ... py> class B(A): ... def f(self, what, *args, **kwargs): ... super(B, self).f(what, *args, **kwargs) ... print 'B.f', what ... py> class C(A): ... def f(self, *args, **kwargs): ... super(C, self).f(*args, **kwargs) ... print 'C.f' ... py> class D(B, C): ... def f(self, what, *args, **kwargs): ... super(D, self).f(what, *args, **kwargs) ... print 'D.f', what ... py> d = D() py> d.f(42) A.f C.f B.f 42 D.f 42 py> d.f(what=13) A.f C.f B.f 13 D.f 13 The problem is that you need to know when you create A that some of the methods in the subclasses might change the signature. Or you need to do this to every method, which is kinda nasty. Definitely take a moment to read Guido's comments on this issue: http://mail.python.org/pipermail/python-dev/2005-January/050656.html The main point is that by adding parameters to functions in a subclass, you violate the Liskov Substitutability Principle. STeVe -- http://mail.python.org/mailman/listinfo/python-list