MetaPython:向类添加方法

时间:2009-07-18 23:03:40

标签: python binding metaprogramming

我想在运行时向类定义添加一些方法。但是,在运行以下代码时,我得到一些令人惊讶的(对我而言)结果。

test.py

class klass(object):
    pass

for i in [1,2]:
    def f(self):
        print(i)
    setattr(klass, 'f' + str(i), f)

在命令行上进行测试时,我得到以下信息:

>>> import test
>>> k = test.klass()
>>> k.f1()
2
>>> k.f2()
2

为什么k.f1()会返回2而不是1?这对我来说似乎很直观。

注释

此测试是在kubuntu机器上使用python3.0完成的。

2 个答案:

答案 0 :(得分:11)

这是绑定的常见问题 - 您希望在函数内部使用i进行早期绑定,而Python正在进行后期绑定。您可以通过这种方式强制执行早期绑定:

class klass(object):
    pass

for i in [1,2]:
    def f(self, i=i):
        print(i)
    setattr(klass, 'f' + str(i), f)

或将f包装为外部函数层,将i作为参数:

class klass(object):
    pass

def fmaker(i):
    def f(self):
        print(i)
    return f

for i in [1,2]:
    setattr(klass, 'f' + str(i), fmaker(i))

答案 1 :(得分:0)

我的猜测是因为print (i)打印i而非按值打印,而打印。因此,当离开for循环时, i 的值 2 ,将两次打印。