Python 动态生成列表名时迭代列表
如何遍历将动态生成其名称的列表Python 动态生成列表名时迭代列表,python,Python,如何遍历将动态生成其名称的列表 boneList_head =['def_neck', 'def_armbase']#hard coded list itemType='head'# result of a user button press ... def selectBones(): global itemType bones =('boneList_'+itemType)# evaluates as a string , not name of a list for
boneList_head =['def_neck', 'def_armbase']#hard coded list
itemType='head'# result of a user button press
...
def selectBones():
global itemType
bones =('boneList_'+itemType)# evaluates as a string , not name of a list
for bone in bones:
cmds.select(bone, tgl=True)
问题是,当我需要将bones作为列表的名称进行求值时,它将作为字符串进行求值。动态生成变量名几乎总是一种糟糕的方法。使用字典
bonedict = {'boneList_head': ['def_neck', 'def_armbase']}
itemType='head'
def selectBones(itemType):
bones = bonedict['boneList_' + itemType]
for bone in bones:
cmds.select(bone, tgl=True)
请忽略我以前的回答(在我的编辑历史中可见),这是愚蠢的——甚至是愚蠢的。但我把它的愚蠢归咎于动态变量名的生成
让我详细说明为什么动态变量名生成是一个坏主意
sys.modules
或其他有问题的构造eval
看起来整洁干净,但实际上并非如此。它可以做任何事。可以做任何事情的函数都是不好的,因为你不能一眼看出它们在这里做什么。一个定义良好的函数只做一件事,而且做得很好;这样,每当你看到这个函数时,你就会确切地知道发生了什么。当您看到eval
时,实际上任何事情都可能发生。从这个意义上说,eval
就像goto
。使用goto
的原因并不是你不能正确使用它;这是因为,对于每一个可能正确使用goto
,都有500000000种可怕的错误使用方法。我甚至不会在这里讨论安全问题,因为最后,这不是eval
的真正问题这是一个丑陋的黑客,但它工作…(当然,你需要得到正确的模块)
这与其他人所说的没有什么不同,但是——我们正在使用
vars
构建一个字典来获取您想要的列表——为什么不首先将一个字典(或正确的列表)传递给函数selectBones呢?我同意其他评论,即您的方法可能不是最好的。但以下措施应该奏效:
bones = eval('boneList_' + itemType)
这将在“boneList_head”上运行python解释器,并返回列表
注意:正如Adam Mihalcin在评论中提到的,您应该非常小心,不要仅对您信任或已验证的数据运行eval。恶意用户可以向itemType变量中插入任意代码以访问操作系统等。将正确的列表作为参数传递到
selectBones
中有什么问题?过于依赖全局变量,尤其是在更多全局变量之间切换,往往会导致代码脆弱。与此密切相关的是,您可以将列表放入一个键入其名称的字典中吗?迭代元组不会产生任何有用的结果-OP希望迭代名为boneList\u head
的列表。我会投反对票,除非有人建议我使用字典。@AdamMihalcin,啊,是的,非常好。哎呀!字典和eval('boneList_uu'+itemType)一样有效。为什么字典优越?这是3D美工GUI工具的一部分,一切都是点击按钮,没有文本输入。@Mambo4,字典访问不仅更安全、更干净,而且速度也快得多——在我使用timeit
进行的测试中,这个用例大约是这个用例的200倍。这是因为它不必像eval()
那样解析和编译Python代码。请注意,将来查看本文的任何人:如果itemType
是任何类型的用户提供的字符串(或在您的控制之外生成),请不要使用此代码。Python的eval
将执行任意代码,允许生成itemType
的人对您的系统进行各种恶劣的操作。您不能过分强调@AdamMihalcin的注释,但是,+1是一个非常简单的解决方案。@AdamMihalcin:谢谢,我更新了我的答案,包括了您的警告
bones = eval('boneList_' + itemType)