bra*_*rad 1 python binding metaprogramming
我想在运行时向类定义添加一些方法.但是,在运行以下代码时,我得到一些令人惊讶的(对我而言)结果.
class klass(object):
pass
for i in [1,2]:
def f(self):
print(i)
setattr(klass, 'f' + str(i), f)
Run Code Online (Sandbox Code Playgroud)
在命令行上进行测试时,我得到以下信息:
>>> import test
>>> k = test.klass()
>>> k.f1()
2
>>> k.f2()
2
Run Code Online (Sandbox Code Playgroud)
为什么k.f1()返回2而不是1?这似乎与我相反.
该测试是在kubuntu机器上使用python3.0完成的.
Ale*_*lli 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)
Run Code Online (Sandbox Code Playgroud)
或者通过将f作为参数将f包装到外部函数层中:
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))
Run Code Online (Sandbox Code Playgroud)