class C(object): def __init__(self, value): self._value = value def _get_value(self): return self._value value = property(_get_value)# all is fine, value calls C._get_value:assert C(10).value == 10Here is what's happening: an instance of a property class is created and a reference to C._get_value is stored in it. Next time c.value is referenced, the property calls the original method. The problem is, the reference is bound to the particular class C, and so if you inherit from it, you should not expect the property to be rebound to the ancestor class'es method:
class D(C): def _get_value(self): return self._value + 1 # now, this still calls C._get_value:assert D(10).value != 11The properties are thus non-polymorphic. There is one way to make them such by introducing late binding,
class C(object): ... value = property(lambda self: self._get_value())but I personally find it cumbersome.