我@property
用来确保对对象实例变量的更改由我需要的方法包装。
当一个实例有一个逻辑上不应该改变的变量时怎么办?例如,如果我正在为 Process 创建一个类,则每个 Process 实例都应该有一个 PID 属性,该属性将经常被访问但不应更改。
处理试图修改该实例变量的人的最 Pythonic 方式是什么?
只是相信用户不要试图改变他们不应该改变的东西吗?
如果实例变量被更改,使用属性但引发异常?
还有什么?
我@property
用来确保对对象实例变量的更改由我需要的方法包装。
当一个实例有一个逻辑上不应该改变的变量时怎么办?例如,如果我正在为 Process 创建一个类,则每个 Process 实例都应该有一个 PID 属性,该属性将经常被访问但不应更改。
处理试图修改该实例变量的人的最 Pythonic 方式是什么?
只是相信用户不要试图改变他们不应该改变的东西吗?
如果实例变量被更改,使用属性但引发异常?
还有什么?
在变量名前加上__
,并创建只读属性,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
简单地信任用户不一定是坏事;如果您只是编写一个快速的 Python 程序,只用一次就扔掉,您很可能只是相信用户不会更改 pid 字段。
恕我直言,强制只读字段的最 Pythonic 方式是使用在尝试设置字段时引发异常的属性。
所以,恕我直言,你对这些东西有很好的直觉。
也许你可以覆盖__setattr__
?在这条线上,
def __setattr__(self, name, value):
if self.__dict__.has_key(name):
raise TypeError, 'value is read only'
self.__dict__[name] = value
只需使用一个属性和一个隐藏属性(以一个下划线为前缀)。
简单属性是只读的!
>>> 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 函数,则您的属性与方法的返回值一样是只读的。