Как реализовать __iadd__ для свойства Python
Я пытаюсь создать свойство Python, в котором добавление на месте обрабатывается другим методом, чем извлечение значения, добавление другого значения и переназначение. Итак, для собственностиx
на объектеo
,
o.x += 5
должен работать иначе, чем
o.x = o.x + 5
Значениеo.x
должно быть таким же, в конце концов, чтобы не запутать ожидания людей, но я хочу сделать добавление на месте более эффективным. (На самом деле операция занимает намного больше времени, чем простое сложение.)
Моей первой идеей было определить в классе
x = property(etc. etc.)
x.__iadd__ = my_iadd
Но это вызывает AttributeError, вероятно, потому чтоproperty
инвентарь__slots__
?
Моя следующая попытка использует объект дескриптора:
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__
как-то обходит это.
Как я могу это сделать? Я не понимаю смысл дескрипторов? Нужен ли метакласс?