Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

206
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!