Python: Operator overloading in a for loop with setattr [duplicate]

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) by def f(self, other, _func=operator_func) and return operator_func(... by return _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.

    – 




Leave a Comment