best practices for making read-only attributes of an object

bruno at modulix onurb at xiludom.gro
Wed Mar 15 14:37:05 EST 2006


Tim Chase wrote:
> I've set up an object and would like to make certain attributes
> read-only (or at least enforce it without doing extra work, as per
> name-mangling or the like).  Ideally, the property would be set in the
> __init__, and then not be allowed to change.
> 
> The best solution I've been able to come up with is something of the form:
> 
> 
> class Foo:
old-style classes are deprecated, please use new-style classes:
class Foo(object):
>   def __init__(self, name, value):
>     self.__dict__['_name'] = name
>     self.value = value
>   def __getattr__(self, attr):
>     name = "_%s" % attr
>     if name in self.__dict__: return self.__dict__[name]
>     raise AttributeError, attr
>   def __setattr__(self, attr, value):
>     if attr == 'value':
>       self.__dict__['value'] = value
>     else:
>       raise AttributeError, attr
> 
> Is there a better ("more pythonic") way to do this? 

One usually uses properties withour setter:

class Parrot(object):
  def __init__(self, is_dead):
    self._is_dead = is_dead

  is_dead = property(fget=lambda self: self._is_dead)

p = Parrot(False)
print p, p.is_dead

> Particularly if it
> plays well with sub-classing Foo.

class DeadBlueParrot(Parrot):
  def __init__(self):
    self._color = "Blue"
    Parrot.__init__(self, True)

  color = property(fget=lambda self: self._color)

d = DeadBlueParrot()
print d, d.color, d.is_dead

HTH
-- 
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"



More information about the Python-list mailing list