我想在一个循环中设置类方法。 这是我的示例代码:
class A:
pass
def gen_func(k):
return classmethod(lambda cls: k)
for k in ('m1', 'm2'):
def gen_func2(k):
return classmethod(lambda cls: k)
setattr(A, 'resolve_%s'%k, classmethod(lambda cls: k)) # print result is: m2, m2
# setattr(A, 'resolve_%s'%k, classmethod((lambda: lambda cls: k)())) # print result is: m2, m2
# setattr(A, 'resolve_%s'%k, gen_func2(k)) # print result is: m1, m2
# setattr(A, 'resolve_%s'%k, gen_func(k)) # print result is: m1, m2 #OK#
print(A.resolve_m1()) # expected print --> m1
print(A.resolve_m2()) # expected print --> m2
预期结果将打印出m1,m2。
但是当我在循环作用域中生成方法时,k
始终是最后一个:m2
。
我只知道这是scope
的原因,如果我们在循环中使用该函数,则该函数会延迟执行。
我在循环作用域之外定义了gen_func
,它起作用了。
但是我想知道确切的原因是什么。 在这种情况下,代码如何在计算机中执行。
我试图从书籍或网站上找到原因,但我对此一无所知。
答案 0 :(得分:0)
谢谢@AndrejKesely
现在我知道它是什么了,您可以使用lambda编写:
setattr(A, 'resolve_%s'%k, classmethod((lambda k: lambda cls: k)(k)))
这里是the introduction of js closures,其中有一些图片有助于理解关闭的过程:
这种范围对象的概念与C或C ++非常不同,在C或C ++中,局部变量存储在堆栈中。在JavaScript中,范围对象改为在堆中分配(或至少它们的行为是这样),因此即使函数已经返回,它们也可能保持分配状态。稍后再讨论。