Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

205
Vistas
Sobrecarga de operadores usando __getattr__ en Python

Estoy tratando de sobrecargar varios operadores a la vez usando la función __getattr__ . En mi código, si llamo a foo.__add__(other) funciona como se esperaba, pero cuando intento foo + bar , no funciona. Aquí hay un ejemplo mínimo:

 class Foo(): def add(self, other): return 1 + other def sub(self, other): return 1 - other def __getattr__(self, name): stripped = name.strip('_') if stripped in {'sub', 'add'}: return getattr(self, stripped) else: return if __name__=='__main__': bar = Foo() print(bar.__add__(1)) # works print(bar + 1) # doesn't work

Me doy cuenta de que sería más fácil en este ejemplo simplemente definir __add__ y __sub__ , pero esa no es una opción en mi caso.

Además, como una pequeña pregunta secundaria, si reemplazo la línea:

 if stripped in {'sub', 'add'}:

con

 if hasattr(self, name):

el código funciona, pero luego mi kernel iPython falla. ¿Por qué sucede esto y cómo podría prevenirlo?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Esto sucede porque los operadores de Python usan una optimización para buscar la función que implementa el operador. Las siguientes líneas son aproximadamente equivalentes:

 foo + 1 type(foo).__add__(foo, 1)

Los operadores se encuentran específicamente solo en el objeto de clase, nunca en la instancia.

bar.__add__(1) llama a __getattr__ para encontrar el atributo que falta en la bar . Esto funciona porque pasa por alto los procedimientos normales de búsqueda del operador.

bar + 1 llama a Foo.__add__(bar, 1) seguido de int.__radd(1, bar) . La búsqueda del primer atributo falla y la segunda opción genera TypeError .

over 4 years ago · Santiago Trujillo Denunciar

0

Además, como una pequeña pregunta secundaria, si reemplazo la línea: [...]

hasattr llama a __getattr__ debajo del capó. Lo que explica lo que vio al hacer if hasattr(self, name): , en realidad ingresa una recursividad infinita ya que ha sobrescrito __getattr__ .

Ver por ti mismo

 class O: def __getattr__(self, attr): print('yooo') return super().__getattr__(attr) # self.__getattr__(attr) -> RecursionError
 >>> hasattr(O(), 'ya') yooo False
over 4 years ago · Santiago Trujillo Denunciar

0

Encontré una solución semi-satisfactoria que no involucra metaclases:

 class Foo(): def add(self, other): return 1 + other def sub(self, other): return 1 - other # Add operators to the type object def get_operator(name): return getattr(Foo, name.strip('_')) for op in ['__add__', '__sub__']: setattr(Foo, op, get_operator(op)) if __name__=='__main__': bar = Foo() print(bar + 2) print(bar - 2)
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda