using super

Scott David Daniels Scott.Daniels at Acm.Org
Mon Dec 31 11:03:22 EST 2007


Steven D'Aprano wrote:
> ...
> I'm not sure if this is your only problem or not, but super() only works 
> with new-style classes, not with classic classes. You must inherit from 
> object, or it cannot possibly work.
> 
> Change "class A" to "class A(object)".
Absolutely correct.

However, the suggested simpler code cannot work on any released Python:

> def chain(meth):  # A decorator for calling super.
>     def f(self, *args, **kwargs):
>         result = meth(self, *args, **kwargs)
>         S = super(self.__class__, self)
This line is the problem.  The class parameter needs to be the class
name (B in this case) in which the chaining method is defined, not that
of the object itself.

>         getattr(S, meth.__name__)(*args, **kwargs)
>         return result
>     f.__name__ = "chained_" + meth.__name__
>     return f
> 
> 
> class A(object):
>     def foo(self, x):
>         print "I am %s" % self
>         return x
> 
> class B(A):
>     @chain
>     def foo(self, x):
>             print "This is B!!!"
>             return x + 1

You'll see the problem once you figure out what goes wrong with:
   class C(B):
       @chain
       def foo(self, x):
               print "This is C!!!"
               return x + 2

   C().foo(5)


As to the original idea, better to give it up.
Typically code for a "chained" method "foo" that
returns a result will want to (in some way) use
the result from that call in forming its result.
Python's super allows you to place that call where
it belongs in your code (perhaps after some logging
is enabled, for example) and not just "at the spot
the guru insists the chaining happens."  The recursion-
like call to the super method is placed explicitly
in Python so you can see how it works.  If super is
too tough to explain, I expect single inheritance is
all you are using.  simply remind people to call
A.foo(self, <args>) within the definition of foo in
B.

--Scott David Daniels
Scott.Daniels at Acm.Org



More information about the Python-list mailing list