Question

I use @property to ensure that changes to an objects instance variables are wrapped by methods where I need to.

What about when an instance has an variable that logically should not be changed? Eg, if I'm making a class for a Process, each Process instance should have a PID attribute that will frequently be accessed but should not be changed.

What's the most Pythonic way to handle someone attempting to modify that instance variable?

  • Simply trust the user not to try and change something they shouldn't?

  • Use property but raise an exception if the instance variable is changed?

  • Something else?

Was it helpful?

Solution

Prepend name of the variable with __, and create read-only property, Python will take care of exceptions, and variable itself will be protected from accidental overwrite.

class foo(object):
    def __init__(self, bar):
        self.__bar = bar

    @property
    def bar(self):
        return self.__bar

f = foo('bar')
f.bar         # => bar
f.bar = 'baz' # AttributeError; would have to use f._foo__bar

OTHER TIPS

Simply trusting the user is not necessarily a bad thing; if you are just writing a quick Python program to be used once and thrown away, you might very well just trust that the user not alter the pid field.

IMHO the most Pythonic way to enforce the read-only field is to use a property that raises an exception on an attempt to set the field.

So, IMHO you have good instincts about this stuff.

Maybe you can override __setattr__? In the line of,

def __setattr__(self, name, value):
    if self.__dict__.has_key(name):
        raise TypeError, 'value is read only'
    self.__dict__[name] = value

Simply use a property and a hidden attribute (prefixed with one underscore).

Simple properties are read-only!

>>> class Test (object):
...  @property
...  def bar(self):
...   return self._bar
... 
>>> t = Test()
>>> t._bar = 2
>>> t.bar
2
>>> t.bar = 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

Hiding with double underscore is not used to hide the implementation, but to make sure you don't collide with a subclass' attributes; consider a mixin for example, it has to be very careful!

If you just want to hide the attribute, use a single underscore. And as you see there is no extra magic to add -- if you don't define a set function, your property is just as read-only as the return value of a method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top