Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.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 - Fatal编程技术网

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

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

  • 因为动态变量生成屏蔽了变量名定义。很难区分定义了什么和没有定义什么,因此很容易意外地重新定义变量。这是潜在bug的主要来源

  • 因为动态变量操作将状态更改隐藏在另一层模糊处理下。在某种程度上,无论何时创建词典或列表,都是如此。但人们希望列表和字典需要额外的思考。另一方面,变量名应该非常简单。当变量的定义和重新定义需要深入思考才能理解时,一定是出了问题

  • 因为动态变量生成会污染名称空间。如果有太多的变量,必须自动生成它们,那么它们应该存在于自己的名称空间中,而不是函数的局部变量中,而且肯定不存在于全局名称空间中。在linux内核风格指南中,Linus Torvalds建议,如果一个函数包含5-10个以上的局部变量

  • 因为动态变量生成有助于提高效率,这是一件坏事。如果你给字典赋值,你可以来回传递字典,直到奶牛回家,任何人都需要知道的就是那本字典。如果您在模块的全局命名空间中动态创建变量名,那么如果另一个模块想要访问这些变量名,它必须知道它们的生成方式、该模块中定义了哪些其他变量,等等。此外,传递变量变得更加复杂——您必须传递对模块本身的引用,可能使用
    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)