class 定义中的 NameError

NameError within class definition

我想定义一个class如下:

class ConfigManager:
    @classmethod
    def load_config(cls):
        # do some complex stuff to load something
        return config

    __CONFIG = ConfigManager.load_config()

    @classmethod
    def get_config(cls):
        return cls.__CONFIG

然后当我 运行 以下代码时,它报告 NameError:

x = ConfigManager.get_config()
Traceback (most recent call last):
  File "test.py", line 1, in <module>
    class ConfigManager:
  File "test.py", line 7, in ConfigManager
    __CONFIG = ConfigManager.load_config()
NameError: name 'ConfigManager' is not defined

为什么会出现这个错误?是不是因为Python的代码是解释执行的,到第7行的时候,class ConfigManager还没有定义完?

一个 class 对象仅以其名称存在 class 主体和所有 class 装饰器被评估之后。这意味着您不能在 ConfigManager 主体内部使用名称 ConfigManager。此 包括您在 class 完成之前调用的任何函数或方法。

在构建 class 主体时,您可以引用先前在 class 主体中定义的名称和先前在 class 主体之外定义的名称。

external_name = 'External'

class Demo:
    internal_name = 'Internal'
    print('Body see', external_name, internal_name)
    # throws an error
    print('Body does not see', late_internal_name, late_external_name)
    late_internal_name = 'LateInternal'

late_external_name = 'LateExternal'

这意味着您可以定义一个函数来加载您的配置只要它不需要class对象。请注意,即使在 class 内部定义,这在您访问它时也不是 (class-) 方法。

class ConfigManager:
    # not a method - does not receive cls/self
    def load_config():
        # do some complex stuff to load something
        return {}

    # call helper as a regular function
    __CONFIG = load_config()
    # clean up helper since it is not a proper method
    del load_config

    @classmethod
    def get_config(cls):
        return cls.__CONFIG

或者,如果需要,您可以延迟加载配置。

class ConfigManager:
    _CONFIG = None

    @classmethod
    def _load_config(cls):
        # do some complex stuff to load something
        return {}

    @classmethod
    def get_config(cls):
        if cls._CONFIG is None:
            cls._CONFIG = cls._load_config()
        return cls._CONFIG