Reuse base-class implementation of classmethod?

Bengt Richter bokr at oz.net
Mon Oct 31 22:11:32 EST 2005


On Tue, 01 Nov 2005 00:24:37 GMT, "Giovanni Bajo" <noway at sorry.com> wrote:

>Hello,
>
>what's the magic needed to reuse the base-class implementation of a
>classmethod?
>
>class A(object):
>   @classmethod
>   def foo(cls, a,b):
>       # do something
>       pass
>
>class B(A):
>    @classmethod
>    def foo(cls, a, b):
>         A.foo(cls, a, b)   # WRONG!
>
>I need to call the base-class classmethod to reuse its implementation, but I'd
>like to pass the derived class as first argument.
>-- 
>Giovanni Bajo
>
>
Maybe define a funny-class-method decorator?
(nothing below tested beyond what you see ;-)

 >>> def funnycm(m):
 ...     return property(lambda cls: m.__get__(type(cls), type(type(cls))))
 ...
 >>> class A(object):
 ...     @funnycm
 ...     def foo(cls, a, b):
 ...         print cls, a, b # do something
 ...
 >>> class B(A):
 ...     pass  # just inherit
 ...
 >>> a=A()
 >>> a.foo(1,2)
 <class '__main__.A'> 1 2
 >>> b=B()
 >>> b.foo(1,2)
 <class '__main__.B'> 1 2

Or more directly, a custom descriptor (with dynamic method replacement for good measure ;-)

 >>> class funnycm(object):
 ...     def __init__(self, f): self._f = f
 ...     def __get__(self, inst, cls=None):
 ...         return self._f.__get__(inst is None and cls or type(inst))
 ...     def __set__(self, inst, m): self._f = m  # replace method
 ...
 >>> class A(object):
 ...     @funnycm
 ...     def foo(cls, a, b):
 ...         print cls, a, b # do something
 ...
 >>> class B(A):
 ...     pass  # just inherit
 ...
 >>> a=A()
 >>> a.foo(1,2)
 <class '__main__.A'> 1 2
 >>> b=B()
 >>> b.foo(1,2)
 <class '__main__.B'> 1 2
 >>> A.foo(3,4)
 <class '__main__.A'> 3 4
 >>> B.foo(3,4)
 <class '__main__.B'> 3 4
 >>> a.foo = lambda cls, *args: repr(args)
 >>> a.foo('what','now','then?')
 "('what', 'now', 'then?')"
 >>> b.foo('eh?')
 "('eh?',)"
 >>> B.foo()
 '()'

Vary to taste ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list