简体   繁体   English

从同一个类中调用类成员变量会在Python中产生NameError

[英]Calling a class member variable from within the same class gives a NameError in Python

I'm trying to call a class member variable from within its class, but I get a NameError: name '...' is not defined . 我正在尝试从其类中调用类成员变量,但我得到一个NameError: name '...' is not defined

A similar situation is created by means of the following minimum working example: 通过以下最小工作示例创建了类似的情况:

from pprint import pprint


class MyClass:

    _my_class_variable = {'key_0': 0,
                          'key_1': 1}
    _my_keys = _my_class_variable.keys()

    pprint(_my_class_variable)  # WORKS!
    pprint([value for value in _my_class_variable.values()])  # WORKS!
    pprint([_my_class_variable[key] for key in _my_keys])  # DOES NOT WORK!
    pprint([_my_class_variable[key] for key in _my_class_variable.keys()])  # DOES NOT WORK!

which returns NameError: name '_my_class_variable' is not defined . 返回NameError: name '_my_class_variable' is not defined

How is it possible that the first two pprint command work but not the last two pprint commands? 前两个pprint命令怎么可能工作,而不是最后两个pprint命令?

Everything in the list comprehension is run in a separate scope (as a function, basically), except for the iterable used for the loop. 除了用于循环的迭代之外,列表解析中的所有内容都在一个单独的作用域中运行(基本上作为一个函数)。 So, on the lines that don't work, _my_class_variable is not defined. 因此,在不起作用的行上, _my_class_variable

One way to solve this would be to make sure that you pass _my_class_variable to an immediately executing lambda function so that it's available in the list comprehension's scope : 解决此问题的一种方法是确保将_my_class_variable传递给立即执行的lambda函数,以便它在列表_my_class_variable的范围内可用:

pprint((lambda _my_class_variable : [_my_class_variable[key] for key in _my_class_variable.keys()])(_my_class_variable))  # DOES WORK!
# or
pprint((lambda _my_class_variable=_my_class_variable : [_my_class_variable[key] for key in _my_class_variable.keys()])())  # DOES WORK!

Why does this work? 为什么这样做? List comprehensions get their own separate scope in Python 3 and are wrapped in a temporary function object and called immediately. 列表推导在Python 3中获得它们自己的独立范围,并包含在临时函数对象中并立即调用。 If you were to create an explicit scope for the _my_class_variable , like in a function, its scope will be considered when resolving _my_class_variable . 如果要为_my_class_variable创建显式范围,就像在函数中一样,在解析_my_class_variable时将考虑其范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM