property() usage - is this as good as it gets?

Miles semanticist at gmail.com
Fri Aug 22 13:49:26 EDT 2008


On Fri, Aug 22, 2008 at 12:18 PM, David Moss <drkjam at gmail.com> wrote:
> Hi,
>
> I want to manage and control access to several important attributes in
> a class and override the behaviour of some of them in various
> subclasses.
>
> Below is a stripped version of how I've implemented this in my current
> bit of work.
>
> It works well enough, but I can't help feeling there a cleaner more
> readable way of doing this (with less duplication, etc).

It could certainly be made more concise, without changing the meaning:

###

from operator import attrgetter
class attrsetter(object):
    def __init__(self, attr):
        self._attr = attr
    def __call__(self, object, value):
        setattr(object, self._attr, value)
def defaultproperty(attr):
    return property(attrgetter(attr), attrsetter(attr))

class A(object):
    def __init__(self):
        self._x = None
        self._y = None

    x = defaultproperty('_x')
    y = defaultproperty('_y')

class B(A):
    def __init__(self):
        super(B, self).__init__()
        self._z = None

    def _set_x(self, x):
        #   An example subclass 'set' override.
        if x == 10:
            raise Exception('%r is invalid!' % x)
        self._x = x

    x = property(A.x.fget, _set_x)
    z = defaultproperty('_z')
    # You really don't need to do this, but you can if you want
    del _set_x

###

But, given the example you gave, you could also write things this way
(aside from no longer forbidding deleting the properties, which really
shouldn't be necessary):

###

class A(object):
    def __init__(self):
        self.x = None
        self.y = None

class B(A):
    def __init__(self):
        super(B, self).__init__()
        self._x = self.x
        self.z = None

    def _set_x(self, x):
        #   An example subclass 'set' override.
        if x == 10:
            raise Exception('%r is invalid!' % x)
        self._x = x

    x = property(attrgetter('_x'), _set_x)

###

It's difficult to know exactly what would work best for you without a
better idea of how your properties override each other.

-Miles



More information about the Python-list mailing list