python properties and inheritance

I don't agree that the chosen answer is the ideal way to allow for overriding the property methods. If you expect the getters and setters to be overridden, then you can use lambda to provide access to self, with something like lambda self: self.<property func>.

This works (at least) for Python versions 2.4 to 3.6.

If anyone knows a way to do this with by using property as a decorator instead of as a direct property() call, I'd like to hear it!

Example:

class Foo(object):
    def _get_meow(self):
        return self._meow + ' from a Foo'
    def _set_meow(self, value):
        self._meow = value
    meow = property(fget=lambda self: self._get_meow(),
                    fset=lambda self, value: self._set_meow(value))

This way, an override can be easily performed:

class Bar(Foo):
    def _get_meow(self):
        return super(Bar, self)._get_meow() + ', altered by a Bar'

so that:

>>> foo = Foo()
>>> bar = Bar()
>>> foo.meow, bar.meow = "meow", "meow"
>>> foo.meow
"meow from a Foo"
>>> bar.meow
"meow from a Foo, altered by a Bar"

I discovered this on geek at play.


I simply prefer to repeat the property() as well as you will repeat the @classmethod decorator when overriding a class method.

While this seems very verbose, at least for Python standards, you may notice:

1) for read only properties, property can be used as a decorator:

class Foo(object):
    @property
    def age(self):
        return 11

class Bar(Foo):
    @property
    def age(self):
        return 44

2) in Python 2.6, properties grew a pair of methods setter and deleter which can be used to apply to general properties the shortcut already available for read-only ones:

class C(object):
    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

Another way to do it, without having to create any additional classes. I've added a set method to show what you do if you only override one of the two:

class Foo(object):
    def _get_age(self):
        return 11

    def _set_age(self, age):
        self._age = age

    age = property(_get_age, _set_age)


class Bar(Foo):
    def _get_age(self):
        return 44

    age = property(_get_age, Foo._set_age)

This is a pretty contrived example, but you should get the idea.