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

时间:2015-09-03 07:53:25

标签: python class scope list-comprehension

我想使用另一个类变量将dict构造为类变量。 这确实在循环中有效(请参阅下面的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)) )

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

显然,在类变量的上下文中列表理解和字典理解的可能性存在细微差别。我现在认为这是一个错误,但可以随意给出另一种解释。

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

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

1 个答案:

答案 0 :(得分:1)

此词典理解将适合您的需求:

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