def __init__(self, value):
self._value = value
value = property(_get_value)
# all is fine, value calls C._get_value:
assert C(10).value == 10
Here 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:
return self._value + 1
# now, this still calls C._get_value:
assert D(10).value != 11
The properties are thus non-polymorphic. There is one way to make them such by introducing late binding,
value = property(lambda self: self._get_value())
but I personally find it cumbersome.