Python 在循环中动态定义方法,以模拟数值对象,但所有方法都接收上一次迭代的值,为什么?

Python 在循环中动态定义方法,以模拟数值对象,但所有方法都接收上一次迭代的值,为什么?,python,numpy,side-effects,python-xarray,pint,Python,Numpy,Side Effects,Python Xarray,Pint,我试图用下面的代码动态设置方法来模拟数值对象。但是,每个方法都设置为循环中的最后一个。为什么会发生这种情况?我如何说服Python使用DWIM #!/usr/bin/env python3.5 class Foo(float): pass for tp in ("add", "sub", "mul", "truediv", "floordiv", "mod", "divmod", "pow"): methname = "__{:s}__".format(tp) prin

我试图用下面的代码动态设置方法来模拟数值对象。但是,每个方法都设置为循环中的最后一个。为什么会发生这种情况?我如何说服Python使用DWIM

#!/usr/bin/env python3.5
class Foo(float):
    pass

for tp in ("add", "sub", "mul", "truediv", "floordiv", "mod", "divmod", "pow"):
    methname = "__{:s}__".format(tp)
    print("defining", methname)
    def func(self, other):
        x = getattr(super(Foo, self), methname)(other)
        print("I calculated x={:.3f}!".format(x))
        return x
    func.__name__ = methname
    setattr(Foo, methname, func)

if __name__ == "__main__": # test
    print("Addition", Foo(3) + Foo(3))
    print("Multiplication", Foo(3) * Foo(3))

$ ./dyn.py
defining __add__
defining __sub__
defining __mul__
defining __truediv__
defining __floordiv__
defining __mod__
defining __divmod__
defining __pow__
I calculated x=27.000!
Addition 27.0
I calculated x=27.000!
Multiplication 27.0

结果27.0由3**3计算,它调用的是在调用上次循环迭代更改的methname时实际存储的函数

func中使用的变量引用到全局变量。尝试将func放入另一个方法中,并将循环变量作为参数传递,这样包含func的函数中的局部变量现在是常量,不会被循环更改

#create function with the given name
# \return the function
def makeFunc(tp):
    methname = "__{:s}__".format(tp)
    print("defining", methname)
    def func(self, other):
        x = getattr(super(Foo, self), methname)(other)
        print("I calculated x={:.3f}!".format(x))
        return x
    func.__name__ = methname
    return func


for tp in ("add", "sub", "mul", "truediv", "floordiv", "mod", "divmod", "pow"):
    func=makeFunc(tp)
    setattr(Foo, func.__name__, func)

当然虽然我没有嵌套任何函数,但我还是用链接的答案解决了这个问题。将
methname=methname
添加到
func
的签名中就成功了。