importlib.reload对Enum对象比较的影响及问题原因咨询
importlib.reload对Enum对象比较的影响及问题原因咨询
嗨,这个问题其实和Python模块加载机制以及Enum的本质有关,我来给你拆解清楚:
首先得明白
importlib.reload的核心作用:它会重新执行目标模块的代码,并且替换模块对象内的所有内容——这意味着,模块里定义的类会被重新创建一次,生成一个全新的类对象,哪怕类名和代码完全一致,它在内存中也是和之前旧类完全不同的独立对象。回到你的具体场景,一步步看问题出在哪:
- 你第一次运行
fruits_test.py时,from fruits import Fruit导入的是首次加载fruits模块时创建的Fruit类,这个类的Fruit.Apple是该类的单例实例。 - 当你在Jupyter里调用
reload(fruits)后,Python会重新执行fruits.py中的代码,此时又生成了一个全新的Fruit类,fruits.Fruit会指向这个新类;之后你在Jupyter里执行from fruits import Fruit,拿到的也是这个新类的引用。 - 当你把新类的
Fruit.Apple实例传给check_equality函数时,函数内部的Fruit.Apple其实是旧类的实例——这两个实例虽然名字和枚举值都一样,但属于完全不同的类,所以用==比较时自然返回False。
- 你第一次运行
你可以做个简单的验证来确认:在Jupyter中分别打印
id(fruits_test.Fruit)和id(Fruit),会得到两个不同的内存地址;再打印type(fruits_test.Fruit.Apple)和type(Fruit.Apple),也能看到它们是分属不同的类对象。再补充下Enum的比较逻辑:Enum类的实例采用单例模式,同一个Enum类里的同一个枚举值是同一个实例;但不同Enum类(哪怕结构完全相同)的实例,即便枚举值一致,也会被判定为不相等——因为Enum的
__eq__方法会同时比较实例的枚举值和所属的类。
如果想要避免这个问题,你需要在reload(fruits)之后,重新从fruits模块导入Fruit并更新fruits_test命名空间里的Fruit引用,比如在reload后执行from fruits import Fruit; fruits_test.Fruit = Fruit。
备注:内容来源于stack exchange,提问作者Guest
相关产品推荐
相关产品推荐

