考虑以下简单示例类,该类具有在调用时公开某些内部数据的修改版本的属性:
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
类中?
答案 0 :(得分:2)
@ezod,即使使用描述符协议,也没有直接的方法来做你要求的事情。
value
属性的那种行为完全打破了+=
运算符的语义。
答案 1 :(得分:1)
覆盖__iadd__
魔法。
您需要这样做,因为+=
表示“获取值并添加五个,然后将其设置为结果”。如果您希望它知道该值实际上不是值,则需要更改+=
运算符的语义。
答案 2 :(得分:0)
期望的行为是x.value + = 5应该相当于 x.value = x._value + 5
为什么Python应该知道您的属性是如何实现的(即setter
将其值精确地分配给_x
)?
property
协议允许您为一个名称分配不同的操作(获取,设置,删除)。此协议并不关心这些操作的实现方式。
因此,如果Python对您的代码做出一些假设并尝试修改严格的正向代码逻辑,那将会非常容易混淆。
答案 3 :(得分:0)
我遇到了同样的问题,并用以下方法解决了这个问题:
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
这可能是一个解决方案吗?我忽略了什么吗?