Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何通过循环创建新的Python方法?(尝试将导致所有方法与最后定义的方法相同)_Python_Types_Lambda_Metaprogramming - Fatal编程技术网

如何通过循环创建新的Python方法?(尝试将导致所有方法与最后定义的方法相同)

如何通过循环创建新的Python方法?(尝试将导致所有方法与最后定义的方法相同),python,types,lambda,metaprogramming,Python,Types,Lambda,Metaprogramming,我正在研究从数据动态生成Python类。 (目的是让用户在不了解任何Python的情况下,在一个简单的文件中指定一些软件测试)。 我遇到了意想不到的效果; 作为一个玩具示例,为了快速检查我是否可以根据命名方案创建方法,我执行了以下操作: import unittest attrdict = {} for i in range(3): attrdict["test%s"%i]= types.MethodType(lambda self: i) attrdict["runTest"]=la

我正在研究从数据动态生成Python类。 (目的是让用户在不了解任何Python的情况下,在一个简单的文件中指定一些软件测试)。 我遇到了意想不到的效果; 作为一个玩具示例,为了快速检查我是否可以根据命名方案创建方法,我执行了以下操作:

import unittest

attrdict = {}
for i in range(3):
    attrdict["test%s"%i]= types.MethodType(lambda self: i)
attrdict["runTest"]=lambda self: [eval("self.test%s()"%i) for i in range(3)]
dynTC = type('dynTC', (unittest.TestCase,), attrdict )
现在当我执行

dynTC().runTest()
。。。我希望

[0,1,2] 
作为输出,但实际结果是

[2,2,2]
我希望lambda定义能够绑定循环索引的深层副本,因为它只是一个数字,而不是一个更复杂的结构,但显然这里发生了一些我不理解的事情

我有一种感觉,对于新的Python程序员来说,这可能是一个常见的“陷阱”,但我能想到的所有描述这个问题的术语都非常通用,以至于我的搜索只会返回大量不相关的答案


请你向我解释一下这里发生了什么,而不是我所期望的,最好是我应该做些什么来创造几种不同方法所期望的效果。

问题在于这一行

attrdict["test%s"%i]= types.MethodType(lambda self: i)

当您定义一个引用非其参数的变量的
lambda
时,该变量将从实际调用时定义
lambda
的范围中解析,因此您将始终得到
i
的当前值,而不是定义
lambda
时的
i

在您的情况下,
i
的值将在范围(3)中的
for i循环完成后结束为
2
,因此您需要创建一个闭包,以便在创建
lambda
时将
i
绑定到特定值,方法是将行更改为

attrdict["test%s"%i]= types.MethodType(lambda self, i=i: i)

当lambda被调用时,变量将从调用范围解析为“Not true”。调用它的作用域可能没有变量
i
,或者可能有不同的变量。相反,它总是引用原始范围中的变量。这让我对发生了什么以及有效搜索更多内容的术语有了很好的了解。谢谢大家!@这是一个很好的观点。更新了答案。对types.MethodType(…)的调用实际上不是初始测试的一部分,而且目前为止,该调用缺少参数。很抱歉我粘贴了一个与预期略有不同的工作流阶段。因为答案中已经引用了它,并且没有伤害问题的要点,所以我将保持原样。