NameError within class definition

你说的曾经没有我的故事 提交于 2021-02-04 08:34:07

问题


I wanted to define a class as follows:

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

And then when I run the following code, it reports a 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

Why does this error occur? Is it because Python code is executed by interpretation and when it goes to line 7, class ConfigManager is not yet finished to be defined?


回答1:


A class object only exists by its name after the class body and all class decorators are evaluated. What that means is that you cannot use the name ConfigManager inside the ConfigManager body itself. This also includes any function or method you call before the class is completed.

While building the class body, you can refer to names previously defined in the class body and names previously defined outside of the class body.

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'

This means you can define a function to load your configuration as long as it does not need the class object. Note that even when defined inside the class, this is not a (class-) method by the time you access it.

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

Alternatively, you can lazily load the config if needed.

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


来源:https://stackoverflow.com/questions/57644907/nameerror-within-class-definition

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!