classmethod() not inherited?
Andrew Bennetts
andrew-pythonlist at puzzling.org
Thu Jan 16 05:24:17 EST 2003
On Thu, Jan 16, 2003 at 04:43:35AM -0500, Jack Diederich wrote:
> How is it possible to have classmethods still be
> classmethods in their kids?
>
> -- file Test.py --
> class Base(object):
> def foo(cls):
> return 'BASE!'
> foo = classmethod(foo)
>
> class A(Base):
> def foo(cls):
> return 'some value'
>
> class B(Base):
> def foo(cls):
> return 'some other value'
>
> class Z(Base):
> def foo(cls):
> return 'something else still'
>
> I'd like to have ALL of the derivitives of Base
> have foo as a classmethod, but it doesn't seem
> to be automatic and the following doesn't work
Well, foo *is* a classmethod in the derived classes -- it's just that you're
replacing it with a foo that's not a classmethod <wink>.
If you really want this, you could write a metaclass:
---
class M(type):
def __init__(cls, name, bases, dict):
type.__init__(cls, name, bases, dict)
if callable(dict.get('foo')):
setattr(cls, 'foo', classmethod(dict['foo']))
class Base(object):
__metaclass__ = M # removing this line gives the old behaviour
def foo(cls):
return 'BASE!', cls
# ... A, B and Z as before ...
for x in (Base(), A(), B(), Z()):
print x.foo()
---
This will print:
('BASE!', <class '__main__.Base'>)
('some value', <class '__main__.A'>)
('some other value', <class '__main__.B'>)
('something else still', <class '__main__.Z'>)
Instead of:
('BASE!', <__main__.Base object at 0x8121a6c>)
('some value', <__main__.A object at 0x81141d4>)
('some other value', <__main__.B object at 0x811345c>)
('something else still', <__main__.Z object at 0x814c644>)
Of course, extending it to do this to all overridden classmethods, instead
of being hard-coded to 'foo', is a little trickier, but not much...
-Andrew.
More information about the Python-list
mailing list