Jak zaimplementować __iadd__ dla właściwości Pythona

Próbuję utworzyć właściwość Pythona, w której dodawanie w miejscu jest obsługiwane inną metodą niż pobieranie wartości, dodawanie innej wartości i ponowne przypisywanie. A więc na własnośćx na obiekcieo,

o.x += 5

powinien działać inaczej niż

o.x = o.x + 5

Wartośćo.x w końcu powinien być taki sam, aby nie mylić oczekiwań ludzi, ale chcę sprawić, by miejsce w miejscu było bardziej wydajne. (W rzeczywistości operacja zajmuje dużo więcej czasu niż proste dodanie).

Moim pierwszym pomysłem było zdefiniowanie w klasie

x = property(etc. etc.)
x.__iadd__ = my_iadd

Ale powoduje to błąd AttributeError, prawdopodobnie dlatego, żeproperty narzędzia__slots__?

Moja następna próba używa obiektu deskryptora:

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

Jak widać, wyjątkowy__iadd__ metoda nie jest wywoływana. Mam problem ze zrozumieniem, dlaczego tak jest, chociaż przypuszczam, że obiekt__getattr__ w jakiś sposób go omija.

Jak mogę to zrobić? Czy nie otrzymuję punktu deskryptorów? Czy potrzebuję metaklasy?

questionAnswers(4)

yourAnswerToTheQuestion