开发者

Constant instance variables?

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 prop开发者_如何转开发erty but raise an exception if the instance variable is changed?

  • Something else?


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜