为了账号安全,请及时绑定邮箱和手机立即绑定

如何通过循环创建新的Python方法?

如何通过循环创建新的Python方法?

HUX布斯 2021-03-30 19:15:46
我正在研究从数据动态生成Python类。(目的是让用户在不知道任何Python的情况下,在一个简单的文件中指定一些软件测试)。我遇到了意想不到的效果;作为一个玩具示例,可以快速检查是否可以根据命名方案创建方法,我做了以下工作:import unittestattrdict = {}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程序员来说可能是一个常见的“陷阱”,但是我能想到的用来描述问题的所有术语都是如此通用,以至于我的搜索仅返回了大量无关的答案。您能否向我解释这里发生了什么,而不是我的预期,最好还应说明为实现几种/ different /方法的理想效果而应该做的事情。
查看完整描述

1 回答

?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

问题是这条线...

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

当您定义一个lambda引用了不是其参数之一的变量的变量时,该变量将在lambda实际调用该变量时从定义该变量的作用域中进行解析,因此您将始终获得的当前值i是,而不是i定义时的值lambda

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

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


查看完整回答
反对 回复 2021-04-06
  • 1 回答
  • 0 关注
  • 145 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信