Python中是否可使用in运算符判断枚举是否在枚举集合中?
Python枚举中
in运算符的可行性与底层差异 结论
用in判断枚举是否在集合里完全可行,不会有隐藏问题,只是和官方推荐的is写法在底层逻辑上有区别。
为什么in可行?
Python的Enum是单例实现,每个枚举成员在程序中只有一个实例。而集合的in判断依赖两点:
- 元素的哈希值一致
- 元素间的
==比较返回True
Enum类默认的__hash__方法基于成员的name和value生成,同一个枚举成员的哈希值固定;同时默认的__eq__方法直接做身份比较(等价于is),所以当你把枚举成员放进集合后,用目标枚举实例做in判断时,哈希匹配且==成立,结果完全符合预期。
与is写法的底层差异
is运算符:直接比较两个对象的内存地址(即身份标识id()),是最直接的单例判断方式,没有额外计算,效率最高。比如foo is MyEnum.STR1就是直接校验foo和MyEnum.STR1是不是同一个内存对象。in集合判断:会先计算foo的哈希值,找到集合中对应的哈希桶,再在桶内用==逐个比较元素。但因为枚举的__eq__等价于is,所以最终结果和用多个is加逻辑或的写法一致,只是多了哈希计算和桶查找的步骤。不过对于元素数量少的集合,这点性能差异完全可以忽略。
注意事项
如果你的枚举类自定义了__eq__或__hash__方法,可能会破坏in判断的正确性——比如重写__eq__后让不同实例返回True,或者哈希值计算逻辑改变。但官方文档明确不推荐重写枚举的这两个方法,因为会打破单例的语义,只要遵循最佳实践,就不会有问题。
示例验证
你的示例代码中两种写法都会输出两次foo,结果完全一致:
from enum import auto, StrEnum class MyEnum(StrEnum): STR1 = auto() STR2 = auto() STRN = auto() def main(): foo = MyEnum.STR1 if foo in {MyEnum.STR1, MyEnum.STR2}: # 完全可行 print("foo") if foo is MyEnum.STR1 or foo is MyEnum.STR2: # 官方推荐写法 print("foo") main()
内容的提问来源于stack exchange,提问作者z3us
相关产品推荐
相关产品推荐

