静态类范围中的python嵌套字典理解:未定义变量 [英] python nested dictionary comprehension in static class scope: variable not defined
问题描述
我有以下代码:
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)
要了解为什么嵌套不是问题,请查看此限制"的说明中的示例,在Python语言参考的执行模型部分中:
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屋!