首页 > 解决方案 > Python:伪枚举 - 作为枚举的类 - 如何避免循环导入

问题描述

我想在我的 python 项目中创建一个伪枚举。这些值实际上是类。

# file my_enums.py

import MyClass1
import MyClass2
import MyClass3

class MyEnum:
    MY_CLASS_1 = MyClass1
    MY_CLASS_2 = MyClass2
    MY_CLASS_3 = MyClass3



# file my_class1.py
import MyEnum

class MyClass1:
    def foo(self, x):
        print(isinstance(x, MyEnum.MY_CLASS_2))

这样做会导致循环导入错误。我希望能够在 isinstance 函数中使用 MyEnum 值,并将枚举导入到定义其中一些类的模块中。有没有办法这样做?

解决方案:

# file my_enums.py

import MyClass1
import MyClass2
import MyClass3

class MyEnum:

    MY_CLASS_1 = None
    MY_CLASS_2 = None
    MY_CLASS_3 = None
    
    @classmethod
    def define(cls):
        cls.MY_CLASS_1 = MyClass1

MyEnum.define()

标签: python-3.xenumspython-import

解决方案


要记住的是,当一个模块被加载时,它会被执行——但只有顶级语句和顶级类的直接内部;函数和方法的主体在实际调用之前不会被评估。

# example module

CONSTANT = 7                    # top-level, executed

def a_func(value=CONSTANT):     # top-level, executed
    return value + 9            # body, not executed

class a_class(metaclass=SomeMeta):  # top-level, executed (and error as SomeMeta
                                    # has not been defined nor imported)
    CLS_CONSTANT = 3                # top-level class body, executed

    def a_method(self):             # executed
        return self.CLS_CONSTANT + FUTURE_CONSTANT  # method body, not executed

FUTURE_CONSTANT = 11

因此,在您的示例中,您需要确保并且不使用将在导入期间执行的MyEnum任何地方my_class1.py,并将导入放在my_enums.py最后 - 然后my_enums.py在其导入期间执行时,它将能够导入my_class1哪个点,定义类。


推荐阅读