我试图创建一个Python属性,其中就地添加是通过不同的方法处理而不是检索值,添加另一个值并重新分配。因此,对于一个对象o
上的属性x
,如何为Python属性实现__iadd__
o.x += 5
应该工作不同于
o.x = o.x + 5
的o.x
值应该是在年底相同,以免混淆人们的预期,但我想使就地添加更高效。 (在现实中,操作时间比简单的加法更多的时间。)
我的第一个想法是定义在类,
x = property(etc. etc.)
x.__iadd__ = my_iadd
但由于property
实现__slots__
这引发了一个AttributeError,想必?
我的下一次尝试使用一个描述符对象:
class IAddProp(object):
def __init__(self):
self._val = 5
def __get__(self, obj, type=None):
return self._val
def __set__(self, obj, value):
self._val = value
def __iadd__(self, value):
print '__iadd__!'
self._val += value
return self
class TestObj(object):
x = IAddProp()
#x.__iadd__ = IAddProp.__iadd__ # doesn't help
>>> o = TestObj()
>>> print o.x
5
>>> o.x = 10
>>> print o.x
10
>>> o.x += 5 # '__iadd__!' not printed
>>> print o.x
15
正如你所看到的,特殊__iadd__
方法不叫。我无法理解这是为什么,尽管我猜测对象的__getattr__
在某种程度上绕过了它。
我该怎么做?我没有得到描述符的重点吗?我需要一个元类吗?
我有点困惑这个代码片段。财产获得者不应该返回什么? – senderle 2012-08-16 14:48:22
@senderle噢,哎呀。对subclassing int的问题感到困惑。谢谢! – ecatmur 2012-08-16 14:54:26