常量变量?

时间:2009-10-06 18:56:01

标签: python properties instance setter instance-variables

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

当实例有一个逻辑上不应该更改的变量时怎么样?例如,如果我正在为一个Process创建一个类,那么每个Process实例都应该有一个经常被访问但不应该被更改的PID属性。

处理试图修改该实例变量的人的Pythonic方法是什么?

  • 只需相信用户不要尝试更改 他们不该做的事情?

  • 使用属性但是提高了 如果实例变量是异常 改变了吗?

  • 还有别的吗?

4 个答案:

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