检查 Enum 类型的变量是否在一组枚举中

Check if variable of type Enum is in a set of Enums

提问人:z3us 提问时间:11/11/2023 更新时间:11/11/2023 访问量:53

问:

根据 Python 中 Enums 的文档,由于 Enums 是单例,因此比较主要是指运算符。但是,如果要检查枚举是否在一组枚举中,那么使用运算符是否完全可以?它似乎按预期工作,但如果有任何必须采取的警告,我的知识在这里就不足了。isin

以下代码应足以作为说明性示例:

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}: # is this okay?
        print("foo")

    if foo is MyEnum.STR1 or foo is MyEnum.STR2: # the alternative following the documentation
        print("foo")

main()

我查阅了文档,发现运算符是最佳实践,以及 StackOverflow 上的相关问题。此外,我自己也尝试过一些例子,这似乎按预期工作。然而,我没有成功地找到我确切问题的答案。is

非常感谢任何关于它是否正常,以及较低级别的实际差异可能是什么的见解。

Python 枚举 比较 成员身份

评论


答:

1赞 enzo 11/11/2023 #1

通常,如果 ,则 .这就是平等的反身属性:一个对象应该等于它自己。a is ba == b

通常,if 是可迭代的 和 ,则 。如果包含在 中,则必须至少有一个元素等于 。ba in bany(value == a for value in b)abba

因此,您可以假设

foo is MyEnum.STR1 or foo is MyEnum.STR2

相当于

foo == MyEnum.STR1 or foo == MyEnum.STR2

这相当于

foo in {MyEnum.STR1, MyEnum.STR2}

互换使用它们是安全的,因为集合和枚举都是内置类型,并且没有任何特殊的相等或成员逻辑。

当然,检查 using 是一种很好的做法,但代码的可读性是更好的做法。如果需要与五个枚举值进行比较,哪个代码更具可读性?is

if foo in {MyEnum.STR1, MyEnum.STR2, MyEnum.STR3, MyEnum.STR4, MyEnum.STR5}:
    pass

if foo is MyEnum.STR1 or foo is MyEnum.STR2 or foo is MyEnum.STR3 or foo is MyEnum.STR4 or foo is MyEnum.STR5:
    pass 

评论

1赞 z3us 11/11/2023
你关于可读性的最后一点是我提出这个问题的确切原因。非常感谢您的回答。
1赞 Ethan Furman 11/11/2023 #2

使用 instead 的原因是样式和意图:is==

  • ==告诉您两个对象是否相等
  • is会告诉你这两个对象是否真的是同一个对象

通过 创建自己的对象时,如果未指定方法,则缺省值使用 。class__eq____eq__is

some_obj in some_container

基本上是

for obj in some_container:
    if obj is some_obj or obj == some_obj:
        return True
else:
    return False