inherit and overwrite a property (better its method call)
Peter Otten
__peter__ at web.de
Mon Feb 16 17:17:41 EST 2004
chris wrote:
> hi,
> i am tinkering with properties of new style classes:
>
> class Base(object):
>
> def m(self):
> return 'p of Base'
> p = property(m)
>
> class Sub(Base):
> def m(self):
> return 'p of Sub'
>
> b = Base()
> print b.p # prints 'p of Base'
>
> s = Sub()
> print s.p # prints 'p of Base'!?
>
> i was thinking s.p would use the method m of class Sub and not Base. but
> this does not work, both properties "p" of Base and Sub use method m of
> baseclass Base.
>
> so it seems i cannot overwrite the method p calls to get its value
> without actually repeating the property definition in every subclass, or
> is there a way? the following does work but i want to get rid of the
> second p = property(m)...
>
> class Sub(Base):
> def m(self):
> return 'p of Sub'
> p = property(m)
>
> print b.p # prints 'p of Base'
> s = Sub()
> print s.p # prints 'p of Sub'
>
> am i missing something?
I don't think so. Anyway, I have been tinkering too, and here's what I've
come up with so far:
class inheritableproperty(property):
""" property with overridable accessor functions """
def funcByName(cls, fn):
# helper func
if fn is None: return None
result = getattr(cls, fn.__name__, None)
assert result is None or callable(result)
return result
class typewithinheritableproperties(type):
def __init__(cls, name, bases, dict):
super(typewithinheritableproperties, cls).__init__(name, bases,
dict)
# replace inheritable properties with new instances where
# the accessors are determined by a name lookup in the actual class
for name in dir(cls):
a = getattr(cls, name)
if isinstance(a, inheritableproperty):
setattr(cls, name, inheritableproperty(
funcByName(cls, a.fget),
funcByName(cls, a.fset),
funcByName(cls, a.fdel)
))
class A(object):
__metaclass__ = typewithinheritableproperties
def geta(self): return "A.a"
a = inheritableproperty(geta)
class B(A):
def geta(self): return "B.a"
class C(A): pass
class D(B): pass
print A().a
print B().a
print C().a
print D().a
http://www.python.org/2.2/descrintro.html might also be of interest for you.
It has an example of properties based on naming conventions (class
autoprop).
Peter
More information about the Python-list
mailing list