Tengo una clase que necesita hacer algo de magia con cada operador, como __add__
, __sub__
y así sucesivamente.Operación interceptar operador en la metaclase
En lugar de crear cada función en la clase, tengo una metaclase que define cada operador en el módulo de operador.
import operator
class MetaFuncBuilder(type):
def __init__(self, *args, **kw):
super().__init__(*args, **kw)
attr = '__{0}{1}__'
for op in (x for x in dir(operator) if not x.startswith('__')):
oper = getattr(operator, op)
# ... I have my magic replacement functions here
# `func` for `__operators__` and `__ioperators__`
# and `rfunc` for `__roperators__`
setattr(self, attr.format('', op), func)
setattr(self, attr.format('r', op), rfunc)
El enfoque funciona bien, pero creo que sería mejor si genero el operador de reemplazo solo cuando sea necesario.
de búsqueda de los operadores debe estar en la metaclase porque x + 1
se hace como type(x).__add__(x,1)
en lugar de x.__add__(x,1)
, pero no quede atrapado por __getattr__
ni __getattribute__
métodos.
que no funciona:
class Meta(type):
def __getattr__(self, name):
if name in ['__add__', '__sub__', '__mul__', ...]:
func = lambda:... #generate magic function
return func
Además, la "función" resultante debe ser un método vinculado a la instancia utilizado.
¿Alguna idea sobre cómo puedo interceptar esta búsqueda? No sé si está claro lo que quiero hacer.
Para aquellos cuestionar por qué necesito a este tipo de cosas, marque el código completo here. Esa es una herramienta para generar funciones (solo por diversión) que podría funcionar como reemplazo de lambda
s.
Ejemplo:
>>> f = FuncBuilder()
>>> g = f ** 2
>>> g(10)
100
>>> g
<var [('pow', 2)]>
Sólo para que conste, yo no quiero saber otra forma de hacer lo mismo (no voy a declarar cada operador en la clase ... que habrá aburrido y el enfoque que tengo funciona bastante bien :). Quiero saber cómo interceptar la búsqueda de atributos desde un operador.
"Tengo una clase que necesita hacer magia con cada operador" - ¿Por qué? Parece que está ladrando un árbol muy complicado ... –
@LennartRegebro Estoy escribiendo un generador de funciones usando los operadores en algún objeto. 'f = FuncBuilder(); g = f ** 2 + 1; g (10) == 101'. No es algo muy útil (muchas llamadas a funciones), pero es algo divertido de usar: D – JBernardo
@LennartRegebro Publiqué el código completo. – JBernardo