Python 使用 class 变量的列表理解抛出 NameError

Python list comprehension using a class variable throws NameError

我想使用另一个 class 变量将 dict 构造为 class 变量。 这确实在循环中起作用(参见下面的 order1),但在 dict comprehension 中不起作用(参见下面的 order2)。我收到一条错误消息,指出 choices 未定义。

然而,列表理解确实有效(参见 order3),但这不是我想要的。 编辑: 其实order3也报错,但是在调用的时候,不是在定义的时候,因为它定义的是生成器对象,不是列表

class Foo():
    ALICE = 'TXT42'
    BOB = 'TXT4711'
    CHARLIE = 'TXT23'

    # List of lists for usage in a Django ChoiceField
    choices = (
        (ALICE, 'Alice'),
        (BOB, 'Bob'),
        (CHARLIE, 'Charlie'),
    )

    # Now I want to define an order for my constants in a dict, with
    # order[ALICE] < order[BOB] < order[CHARLIE]

    # This works, but is clumsy
    order1 = {}
    for i in range(len(choices)):
        order1[choices[i][0]] = i

    # This gives an error (but works if 'choices' is global):
    # "NameError: global name 'choices' is not defined"
    order2 = { choices[i][0]: i for i in range(len(choices)) }

    # This gives a list of dicts, not a dict (but doesn't throw an error)
    # My mistake: it gives a generator object. It will throw the same
    # error, if you try to access it or make it a list, 
    # e.g. order3 = list(...)
    order3 = ( { choices[i][0]: i } for i in range(len(choices)) )

当我在函数定义而不是 class 中尝试整个代码时,没有错误。它也适用于 choices 确实是一个全局变量,但不是 class 变量。

显然,在 class 变量的上下文中,列表理解和字典理解的可能性存在细微差别。我暂时认为这是一个错误,但请随时给出其他解释。

Python 尝试过的版本:Debian 下的 2.7.10 和 3.4.3 GNU/Linux


编辑:感谢@BrenBarn 找到了我没有找到的副本。它解释了我在这里遇到的问题。这不是错误,但也不是真正的功能。 ;-)

本词典理解将适合您的需要:

order2 = {choice[0]: idx for idx, choice in enumerate(choices)}