Best way to control assignment to attribute?

Peter Otten __peter__ at web.de
Wed Feb 4 10:41:38 EST 2004


Frank Millman wrote:

> Hi all
> 
> I want to control the assignment of a value to an attribute. Instead
> of allowing it to be changed directly, I want to enforce that a method
> is called, which will perform the assignment subject to various
> checks.
> 
> From reading the manuals, this is one way to do it.
> 
> class frank:
>     def __init__(self,x):
>         self.setval_x(x)
> 
>     def __setattr__(self,name,value):
>         if name == 'x':
>             raise 'cannot change value of x - use setval_x(value)'

I think you shouldn't use string exceptions in new code anymore.

>         else:
>             self.__dict__[name] = value
> 
>     def setval_x(self,value):
>         ok = 1
>         # perform any checks required
>         if ok:
>             self.__dict__['x'] = value
> 
> Is this the best way, or does anyone have any other suggestions?
> 
> I notice that an application can beat this by using the __dict__
> syntax itself. Is there any way to prevent this? Just curious, it is
> not a major concern.
> 
> Any comments will be appreciated.
> 
> Thanks
> 
> Frank Millman

Use new style classes and properties:

>>> class Frank(object):
...     def __init__(self, x):
...             self.x = x
...     def getX(self):
...             return self._x
...     def setX(self, x):
...             if x < 0:
...                     raise ValueError("x must be >= 0")
...             self._x = x
...     x = property(getX, setX)
...
>>> f = Frank(3)
>>> f.x = 2
>>> f.x = -2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 8, in setX
ValueError: x must be >= 0

The main advantage is cleaner code, which will become more obvious as the
number of special attributes increases. Also, checked and normal attribute
access is transparent to the client.

Peter




More information about the Python-list mailing list