我使用@property
来确保对对象实例变量的更改由我需要的方法包装。
当实例有一个逻辑上不应该更改的变量时怎么样?例如,如果我正在为一个Process创建一个类,那么每个Process实例都应该有一个经常被访问但不应该被更改的PID属性。
处理试图修改该实例变量的人的Pythonic方法是什么?
只需相信用户不要尝试更改 他们不该做的事情?
使用属性但是提高了 如果实例变量是异常 改变了吗?
还有别的吗?
答案 0 :(得分:8)
使用__
添加变量的名称,并创建只读属性,Python将处理异常,并且保护变量本身不会被意外覆盖。
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
答案 1 :(得分:3)
简单地信任用户并不一定是坏事;如果你只是编写一个快速的Python程序来使用一次并丢弃,你很可能只是相信用户不会改变pid字段。
恕我直言,强制执行只读字段的最Pythonic方法是使用在尝试设置字段时引发异常的属性。
所以,恕我直言,你对这些东西有很好的直觉。
答案 2 :(得分:1)
也许你可以覆盖__setattr__
?在行中,
def __setattr__(self, name, value):
if self.__dict__.has_key(name):
raise TypeError, 'value is read only'
self.__dict__[name] = value
答案 3 :(得分:1)
只需使用属性和隐藏属性(以一个下划线为前缀)。
简单属性是只读的!
>>> 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
隐藏双下划线不是用来隐藏实现,而是用来确保不与子类的属性冲突;例如,考虑一下mixin,它必须非常小心!
如果您只想隐藏属性,请使用单个下划线。正如你所看到的,没有额外的魔法可以添加 - 如果你没有定义一个set函数,你的属性就像方法的返回值一样只读。