klwire
klwire

Reputation: 133

Correctly importing enumerations in Python

Let's assume the following scenario. In the directory ./lib I have the file 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

In the source directory I have the file ./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()

In both cases, the enumeration is imported as from lib.animal_enum import Animal. The difference is how I import the function get_cat(). In the function animal_test1() it is done directly by from lib.animal_enum import get_cat, in the function animal_test2() the path to the lib directory is added to the sys.path variable and the method is imported as from animal_enum import get_cat.

Now I compare the value Animal.CAT to the result of the function get_cat, which is also Animal.CAT. I expect both comparisons to be True. But instead I get the follwing:

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

Why does the second comparison evaluates to False?

PS: One way to prevent this error is for the animal enumeration to inherit from both int and Enum:

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

Now, in animal_test, integer values are compared and the result is what I expect:

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

Upvotes: 3

Views: 2384

Answers (1)

Prem Anand
Prem Anand

Reputation: 2537

Eventhough you import the same module via different ways, python doesn't know they are the same modules. It still thinks lib.animal_enum and animal_enum are totally different

>>> 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'
>>> 

Upvotes: 4

Related Questions