静态类范围中的python嵌套字典理解:未定义变量 [英] python nested dictionary comprehension in static class scope: variable not defined

查看:85
本文介绍了静态类范围中的python嵌套字典理解:未定义变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

class Chars:
    char_to_number = {
        'a': ['1'],
        'b': ['2'],
        'c': ['3', '6'],
        'd': ['4', '5'],
    }

    number_to_char = {
        number: char
        for char in char_to_number
        for number in char_to_number[char]
    }

现在此代码将返回如下错误: name 'char_to_number' is not defined

Now this code returns an error as such: name 'char_to_number' is not defined

现在看来python无法解析嵌套的字典理解.似乎内部作用域未使用定义char_to_number变量的外部作用域进行更新.

Now it looks like python could not parse the nested dictionary comprehension. It looks like the inner scope was not updated with the outer scope, which defined the char_to_number variable.

我已通过以下实现解决了此代码:

I've solved this code with this implementation:

class Chars:
    char_to_number = {
        'a': ['1'],
        'b': ['2'],
        'c': ['3', '6'],
        'd': ['4', '5'],
    }

    number_to_char = {
        number: char
        for char, optional_numbers in char_to_number.items()
        for number in optional_numbers
    }

这里,我不在内部循环中使用char_to_number变量,而python成功解析了此代码.

Here I'm not using the char_to_number variable in the inner loop, and python succeeded to parse this code.

当然,所有这些都发生在该类的全局范围内. 在全局python作用域中,它不会发生:

Of course, all of that happens in the global scope of the class. In the global python scope, it doesn't happen:

char_to_number = {
    'a': ['1'],
    'b': ['2'],
    'c': ['3', '6'],
    'd': ['4', '5'],
}

number_to_char = {
    number: char
    for char in char_to_number
    for number in char_to_number[char]
}

有人对此有任何线索吗?

Does anyone have any clue about that?

推荐答案

问题的实质不是嵌套.实际上,在类中使用的理解范围存在缺陷.要了解为什么这看起来像缺陷,请从@ gal-ben-david的原始问题中获取代码,并将其放入函数中(添加了print语句和函数调用以生成输出,并确认该代码至少在Python中有效3.6.6):

The essence of the problem is not the nesting. It's the fact that there's a flaw in the scope in comprehensions used within classes. To understand why this looks like a flaw, take the code from the original question by @gal-ben-david and put it in a function (print statement and function call added to generate output and confirm that this code works, at least in Python 3.6.6):

def Chars():
    char_to_number = {
        'a': ['1'],
        'b': ['2'],
        'c': ['3', '6'],
        'd': ['4', '5'],
    }
    number_to_char = {
        number: char
        for char in char_to_number
        for number in char_to_number[char]
    }
    print(number_to_char)

要了解为什么嵌套不是问题,请查看此限制"的说明中的示例,

To understand why nesting is not the problem, take a look at the example in the explanation for this "limitation", in the section on the execution model of the Python language reference:

class A:
    a = 42
    b = list(a + i for i in range(10))

如果这两行出现在类中,则变量"a"不在理解范围内,而是在函数或模块中.我称那是个错误.为了使限制正式化:当在类中使用理解时,仅在for循环中最外层的迭代器可在该理解内访问,而不能从该理解外访问其他变量.

The variable "a" is not in the scope of the comprehension if these two lines appear in a class, but it would be in a function or module. I call that a bug. To formalize the limitation a bit: when a comprehension is used in a class, only the outermost iterator in the for loop(s) is accessible inside the comprehension, but no other variables from outside the comprehension are accessible.

理解被表示为等同于for循环,但显然不是.尽管正在讨论此缺陷的性质(错误或非错误),但我已向开发人员提交了有关理解文档的票证,该文档确实应该突出提及此问题.

Comprehensions are presented as being equivalent to for loops, but obviously they aren't. While the nature of this flaw is being debated (bug or not bug), I've submitted a ticket to the developers about the documentation of comprehensions, which really should mention this problem prominently.

对于@armatita的响应,我没有足够的意见发表意见,但是请注意,这是一种解决方法,不等于原始代码尝试执行的操作,因为它使每个类实例的char_to_number和number_to_char属性而不是每个类实例的char_to_number和number_to_char属性班级本身.我登陆此页面是因为我试图分配类属性.

I don't have enough points to comment on @armatita's response, but note that it's a workaround and not equivalent to what the original code is trying to do, because it makes char_to_number and number_to_char attributes of each class instance and not of the class itself. I landed on this page because I was trying to assign class attributes.

这篇关于静态类范围中的python嵌套字典理解:未定义变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆