Как реализовать __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__каким-то образом обходит его.

Как я могу это сделать? Я не понимаю смысла дескрипторов? Нужен ли мне метакласс?

13
задан ptomato 16 August 2012 в 13:13
поделиться