Estoy intentando crear una propiedad de Python en la que la adición in situ se maneje con un método diferente al de recuperar el valor, agregar otro valor y reasignar. Así, para una propiedad x
en un objeto o
,Cómo implementar __iadd__ para una propiedad de Python
o.x += 5
deben trabajar de manera diferente que
o.x = o.x + 5
El valor de o.x
debe ser el mismo que al final, a fin de no confundir a las expectativas de las personas, pero Quiero hacer que el add in situ sea más eficiente. (En realidad, la operación lleva bastante más tiempo que una simple suma.)
Mi primera idea era definir, en la clase,
x = property(etc. etc.)
x.__iadd__ = my_iadd
Pero esto plantea un AttributeError, presumiblemente porque property
implementa __slots__
?
Mi siguiente intento se utiliza un objeto descriptor:
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 se puede ver, el método especial __iadd__
no se llama. Tengo problemas para entender por qué ocurre esto, aunque supongo que el objeto __getattr__
de alguna manera lo pasa por alto.
¿Cómo puedo hacer esto? ¿No entiendo el sentido de los descriptores? ¿Necesito una metaclase?
Estoy un poco confundido por este fragmento de código. ¿No debería el comprador obtener algo? – senderle
@senderle oh sí, oops. Tengo un poco confuso con los problemas de subclases 'int'. ¡Gracias! – ecatmur