复合赋值的属性设置器?
考虑下面这个简单的例子类,它有一个属性,当你调用它时,会返回一些内部数据的修改版本:
class Foo(object): def __init__(self, value, offset=0): self._value = value self.offset = offset @property def value(self): return self._value + self.offset @value.setter def value(self, value): self._value = value
这个 value.setter
对于普通的赋值操作是没问题的,但在复合赋值(比如加法赋值)时就不太管用了:
>>> x = Foo(3, 2) >>> x.value 5 >>> x.value = 2 >>> x.value 4 >>> x.value += 5 >>> x.value 11
我们希望的行为是,当你写 x.value += 5
时,它应该等同于 x.value = x._value + 5
,而不是 x.value = x.value + 5
。有没有办法在 Foo
类内部,利用属性接口来实现这个功能呢?
4 个回答
1
我也遇到了同样的问题,后来用以下方法解决了:
class Foo(object):
def __init__(self):
self._y = 0
@property
def y(self):
return self._y + 5
@y.setter
def y(self, value):
value -= 5
self._y = value
>>> f = Foo()
>>> f.y
5
>>> f.y += 1
>>> f._y
1
>>> f.y
6
这可能是一个解决办法吗?我有没有忽略什么呢?
1
重写 __iadd__
这个特殊方法。
你需要这么做,因为 +=
的意思是“把这个值加上五,然后把结果设为新的值”。如果你想让它明白这个值其实并不是真正的值,你就需要改变 +=
操作符的含义。
2
@ezod,你问的这个问题没有直接的方法可以解决,即使使用描述符协议也不行。value
属性的这种行为完全打破了+=
运算符的基本意义。