Como implementar __iadd__ para uma propriedade Python

Estou tentando criar uma propriedade Python em que a adição no local é manipulada por um método diferente da recuperação do valor, adicionando outro valor e reatribuindo. Então, para uma propriedadex em um objetoo,

o.x += 5

deve funcionar de forma diferente do que

o.x = o.x + 5

O valor deo.x deve ser o mesmo no final, para não confundir as expectativas das pessoas, mas eu quero fazer o in-loco adicionar mais eficiente. (Na realidade, a operação leva muito mais tempo do que simples adição.)

Minha primeira ideia foi definir, na aula,

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

Mas isso gera um AttributeError, presumivelmente porqueproperty implementa__slots__?

Minha próxima tentativa usa um objeto de descritor:

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

Como você pode ver, o especial__iadd__ método não é chamado. Estou tendo dificuldade em entender por que isso acontece, embora eu suponha que o objeto__getattr__ está de alguma forma ignorando isso.

Como posso fazer isso? Eu não estou recebendo o ponto de descritores? Eu preciso de uma metaclasse?

questionAnswers(4)

yourAnswerToTheQuestion