Declarative properties

Paul Hankin paul.hankin at gmail.com
Thu Oct 11 14:53:03 EDT 2007


On Oct 11, 12:48 pm, Artur Siekielski <artur.siekiel... at gmail.com>
wrote:
> Hi.
>
> I would like to have declarative properties in Python, ie. something
> like slots definitions in defclass in Common Lisp. It seems that even
> Java will have it, using a library (https://bean-properties.dev.java.net/
> ).
>
> I know about 'property' function in Python, but it's normal usage
> isn't declarative, because I have to code imperatively getters and
> setters:
>
> class Person(object):
>    def __init__(self, name):
>       self._name = name
>    def _get_name(self):
>       return self._name
>    def _set_name(self, new_name):
>       self._name = new_name
>    name = property(_get_name, _set_name)
>
> I would like to have something like that:
>
> class Person(object):
>    name = property('_name')

Here's something that does what I think you want. I think your use
case is quite unusual in that you expect the public accessors to
change (keeping private use the same), and that you know you're going
to have a costly rewrite of your class when that happens.

Attributes that are declared with 'magic_attribute' access the private
attribute '_<name>', unless there's a '_get_<name>' or '_set_<name>'
method in which case those are called instead.

def magic_attribute(_name):
    def set(self, value):
        try:
            getattr(self, '_set' + _name)(value)
        except AttributeError:
            setattr(self, _name, value)
    def get(self):
        try:
            return getattr(self, '_get' + _name)()
        except AttributeError:
            return getattr(self, _name)
    return property(get, set)

# An example use...
class C(object):
    x = magic_attribute('_x')
    y = magic_attribute('_y')

    # Override the default set method for x
    def _set_x(self, value):
        self._x = value + ' world'

    # Override the default get method for y
    def _get_y(self):
        return self._y.upper()

# Test it works...
c = C()
c.x = c.y = 'hello'
print c.x
print c.y

# hello world
# HELLO

--
Paul Hankin




More information about the Python-list mailing list