在 Python 中正确导入枚举

Correctly importing enumerations in Python

让我们假设以下场景。在目录 ./lib 中我有文件 animal_enum.py (./lib/animal_enum):

from enum import Enum

class Animal(Enum):
    DOG = 1
    CAT = 2
    COW = 3
    
def get_cat():
    return Animal.CAT

在源目录中我有文件 ./animal_test.py:

def animal_test1():
    from lib.animal_enum import Animal
    from lib.animal_enum import get_cat
    
    print("Results from animal_test1():")
    print(Animal.CAT, get_cat())
    print(Animal.CAT == get_cat())

def animal_test2():
    from lib.animal_enum import Animal
    
    import sys
    sys.path.insert(0, './lib')
    from animal_enum import get_cat
    
    print("Results from animal_test2():")
    print(Animal.CAT, get_cat())
    print(Animal.CAT == get_cat())
    
if __name__ == "__main__":
    animal_test1()
    print('-----')
    animal_test2()

在这两种情况下,枚举都被导入为 from lib.animal_enum import Animal。不同之处在于我如何导入函数 get_cat()。在函数 animal_test1() 中直接由 from lib.animal_enum import get_cat 完成,在函数 animal_test2() 中将 lib 目录的路径添加到 sys.path 变量和方法导入为 from animal_enum import get_cat.

现在我将值 Animal.CAT 与函数的结果 get_cat 进行比较,后者也是 Animal.CAT。我希望这两个比较都是 True。但是我得到了以下信息:

Results from animal_test1():
Animal.CAT Animal.CAT
True
-----
Results from animal_test2():
Animal.CAT Animal.CAT
False

为什么第二次比较的结果是False

PS:防止此错误的一种方法是让动物枚举从 intEnum 继承:

class Animal(int, Enum):
    DOG = 1
    CAT = 2
    COW = 3

现在,在 animal_test 中比较整数值,结果如我所料:

Results from animal_test1():
Animal.CAT Animal.CAT
True
-----
Results from animal_test2():
Animal.CAT Animal.CAT
True

即使您通过不同的方式导入相同的模块,python 也不知道它们是相同的模块。它仍然认为 lib.animal_enumanimal_enum 完全不同

>>> from lib.animal_enum import Animal
>>> from animal_enum import Animal as Animal2
>>> 
>>> Animal == Animal2
False
>>> 
>>> id(Animal)
94046433019280
>>> id(Animal2)
94046433018336
>>> 
>>> Animal.__module__
'lib.animal_enum'
>>> 
>>> Animal2.__module__
'animal_enum'
>>>