Reuse base-class implementation of classmethod?

G

Giovanni Bajo

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.
 
D

David Wahler

Giovanni said:
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.

See the super object. In your case, it can be used like this:

class B(A):
@classmethod
def foo(cls, a, b):
super(B, cls).foo(a, b)

This all assumes you want to modify the behavior of foo in a subclass.
If not, of course, you don't need to override it at all.

-- David
 
B

Bengt Richter

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.
Maybe define a funny-class-method decorator?
(nothing below tested beyond what you see ;-)
... return property(lambda cls: m.__get__(type(cls), type(type(cls))))
... ... @funnycm
... def foo(cls, a, b):
... print cls, a, b # do something
... ... pass # just inherit
... <class '__main__.B'> 1 2

Or more directly, a custom descriptor (with dynamic method replacement for good measure ;-)
... 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
... ... @funnycm
... def foo(cls, a, b):
... print cls, a, b # do something
... ... pass # just inherit
... '()'

Vary to taste ;-)

Regards,
Bengt Richter
 
G

Giovanni Bajo

David said:
See the super object. In your case, it can be used like this:

class B(A):
@classmethod
def foo(cls, a, b):
super(B, cls).foo(a, b)


Ah thanks, I did not realize that super() was the only way of doing the right
thing here!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top