Constant instance variables?

馋奶兔 提交于 2019-12-10 03:26:33

问题


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?


回答1:


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



回答2:


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.




回答3:


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



回答4:


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.



来源:https://stackoverflow.com/questions/1527395/constant-instance-variables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!