动态生成列表名时迭代列表

2024-10-01 09:23:13 发布

您现在位置: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 bone in bones:
        cmds.select(bone, tgl=True)

问题是bones被当作一个字符串来计算,而我需要它作为一个列表的名称来评估。在


Tags: of名称列表def动态headlistbones
3条回答

我同意其他意见,你的方法可能不是最好的。但以下方法应该有效:

bones = eval('boneList_' + itemType)

这将在“boneList_head”上运行python解释器,并返回列表。在

注意:正如AdamMihalcin在评论中提到的,您应该非常小心只对您信任或已验证的数据运行eval。恶意用户可以将任意代码注入itemType变量以访问操作系统等

动态生成变量名几乎总是一种糟糕的方法。使用字典!在

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)

请忽略我以前的回答(在我的编辑历史中可见),这是愚蠢的愚蠢,甚至。但我把它的愚蠢归咎于动态变量名的生成!在

让我详细说明为什么动态变量名生成是个坏主意。在

  1. 因为动态变量生成会屏蔽变量名定义。很难区分什么已经定义,什么没有定义,所以很容易意外地重新定义一个变量。这是潜在错误的主要来源。

  2. 因为动态变量操作将状态更改隐藏在另一层混淆之下。在某种程度上,这是真的任何时候你创建一个字典或一个列表。但有人认为列表和字典需要一些额外的思考。另一方面,变量名应该非常简单。当变量定义和重新定义需要深思熟虑才能理解时,有些事情是错误的。

  3. 因为动态变量生成会污染命名空间。如果有太多的变量需要自动生成它们,那么它们应该存在于它们自己的名称空间中,而不是函数的局部空间中,绝对不是全局名称空间中。linustorvalds在他的linux内核风格指南中建议,如果一个函数有5-10个以上的局部变量,you're doing something wrong

  4. 因为动态变量生成有助于high coupling,这是一件坏事。如果你给字典赋值,你可以来回地传递字典,直到牛回家为止,所有人只需要知道那本字典。如果您在一个模块的全局命名空间中动态创建变量名,那么如果另一个模块想要访问这些变量名,它必须知道它们的生成方式、该模块中定义了哪些其他变量,等等。此外,传递变量变得更加复杂,您必须传递对模块本身的引用,可能使用sys.modules或其他可疑结构。

  5. 因为动态变量生成很难看。eval看起来整洁干净,但实际上不是。它可以做任何事情。可以做任何事情的函数都是不好的,因为你一眼就看不出它们在做什么。一个定义良好的函数只做一件事,而且做得很好;这样,每当你看到这个函数时,你就知道发生了什么。当你看到eval时,实际上任何事情都可能发生。在这个意义上,eval就像goto。带有gotoproblem并不是说你不能正确地使用它;而是说,对于goto的每一种可能的正确使用,都有5亿种可怕的错误使用方法。我甚至不会在这里讨论安全问题,因为归根结底,eval并不是真正的问题。

这是一个丑陋的黑客,但它是有效的…(当然,你需要得到正确的模块)

import sys
boneList_head =['def_neck', 'def_armbase']
itemType='head'
...
def selectBones():
    global itemType
    bones=vars(sys.modules["__main__"])['boneList_'+itemType]
    for bone in bones:
        cmds.select(bone, tgl=True)

这真的和其他人说的没什么不同,但是我们使用vars来构造一个字典来获得你想要的列表,为什么不首先将一个字典(或正确的列表)传递给函数selectBones呢?在

相关问题 更多 >