I have MyEnum
, an enumerate derived from enum
, defined in a myenum.py
file such as :
# myenum.py import enum class MyEnum(enum.Enum): ONE = 1 TWO = 2
Then, I import this file using the importlib.import_module()
method. I create a
an instance of my enumerate, and test its value : it is correct, as intended.
However, if I reload my file, using importlib.reload()
, a
is no longer equal to MyEnum.ONE
. What is causing this ? I’m on Python 3.7.
# test.py import importlib def test_enum(e): print(e, myenum.MyEnum.ONE) print("test is :", e==myenum.MyEnum.ONE) if __name__=='__main__': globals()["myenum"] = importlib.import_module("myenum") a = myenum.MyEnum.ONE test_enum(a) importlib.reload(globals()["myenum"]) test_enum(a)
Result
MyEnum.ONE MyEnum.ONE test is : True MyEnum.ONE MyEnum.ONE test is : False
Edit : After further research, it appears enums in Python are compared by IDs. However, when reimporting the module, the IDs of my enum are changed, which is why the comparison returns False
.
What options would there be to avoid this ID change or allow the comparison to stay True ?
Advertisement
Answer
It’s impossible to avoid the ID change; you made a new class with new instances while instances of the existing class still existed; definitionally, the IDs aren’t allowed to be equal.
If you must allow them to compare equal despite differing identities, you can just override
__eq__
on theenum
to do whatever you like, e.g.:class MyEnum(enum.Enum): ONE = 1 TWO = 2 def __eq__(self, other): if type(self).__qualname__ != type(other).__qualname__: return NotImplemented return self.name == other.name and self.value == other.value def __hash__(self): return hash((type(self).__qualname__, self.name))
I don’t recommend this (proper use of
enum
s will useis
for comparisons, and nothing can make that work, since it relies on the IDs, which per point #1, will always differ), and it’s going to be much slower (removing one of the benefits ofenum
s), but it’s doable if you must allowreload
ing during development. Just make sure to remove thereload
for the production code.