2009-10-06 120 views
6

我使用'property'来确保对象实例变量的更改由我需要的方法包装。常量实例变量?

什么时候一个实例有一个逻辑上不应该改变的变量?例如,如果我为一个Process创建一个类,每个Process实例都应该有一个经常被访问但不应该改变的pid属性。

什么是处理试图修改该实例变量的人最Python的方式?

  • 只要信任用户不要试图改变 他们不应该做的事情?

  • 使用属性,但如果实例变量是 已更改,则会引发异常 ?

  • 还有其他的东西吗?

+0

http://stackoverflow.com/questions/1358711/raising-an-exception-on-updating-a-constant-attribute-in-python – 2009-10-07 10:26:44

回答

6

前置名,并创建只读属性,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 
+0

在最后两行中,你的意思是“f.foo”和“f .foo ='baz'“,对吗? – 2009-10-06 19:10:47

+0

是的,我混合了变量名称。已经更正。 – 2009-10-06 19:12:46

+1

我发现这个名字的“私人”属性比他们的价值更麻烦。单个下划线将使子类更容易,同时仍然向用户传达“不要触及此事”。 – 2009-10-06 20:02:48

1

也许你可以覆盖__setattr__?在的线,以__变量

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

简单地相信用户并不一定是坏事;如果你只是写一个快速的Python程序来使用一次并扔掉,你可能会相信用户不会改变pid字段。

恕我直言,强制只读字段最Pythonic的方式是使用一个属性,在尝试设置字段时引发异常。

所以,恕我直言,你对这个东西有很好的直觉。

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函数,你的属性就像方法的返回值一样只读。