To avoid a lot of copy-paste, I tried to overload multiple operators with a for loop as in the following MWE:
import operator
class X():
def __init__(self, x):
self.x = x
for method_name, operator_func in {'__add__' : operator.add,
'__mul__' : operator.mul}.items():
def f(self, other):
return operator_func(self.x, other.x)
setattr(X, method_name, f)
X(5)+X(2) #-> 10
X(5)*X(2) #-> 10
In the above code, both + and * return the multiplication. On the other hand, the following works as desired:
def f(self, other):
return operator.add(self.x, other.x)
setattr(X, '__add__', f)
def f(self, other):
return operator.mul(self.x, other.x)
setattr(X, '__mul__', f)
X(5)+X(2) #-> 7
X(5)*X(2) #-> 10
What’s the problem with the for loop and how can I get it to work? I am using python 3.11.
Replace
def f(self, other)
bydef f(self, other, _func=operator_func)
andreturn operator_func(...
byreturn _func(...
.Reason is explained e. g. at stackoverflow.com/a/43149803/987358 which applies to usual nested functions in the same way as to lambdas. The recommended solution with
partial
is cleaner than my suggestion.