如何静态防止 str == enum 比较?

Kam*_*Cuk 4 python enums python-3.x python-3.7

我经常犯以下错误:

import enum

class StatusValues(enum.Enum):
    one = "one"
    two = "two"

def status_is_one(status: str):
    return status == StatusValues.one
Run Code Online (Sandbox Code Playgroud)

String 永远不会是枚举类。问题是它应该是StatusValues.one.value

是否有一个strcmp(status, StatusValues.one)-ish 函数,以便我的pyright在我将字符串与类进行比较时会出错?有没有好的方法来防止此类错误?

pla*_*mut 5

是的,这可能是一个陷阱:默认情况下,我们不能直接将字符串与枚举成员进行比较:

>>> status = "two"
>>> status == StatusValues.two
False
Run Code Online (Sandbox Code Playgroud)

必须记住将字符串与枚举成员的进行比较.value,这也有点冗长:

>>> "two" == StatusValues.two.value
True
Run Code Online (Sandbox Code Playgroud)

幸运的是,有一个解决方案,甚至在文档中也提到过,但它曾经(Python 3.11 之前)在一个很容易被忽略的部分(恕我直言)。我们可以混合使用一种类型的枚举成员:

class IntEnum(int, Enum):
    pass
Run Code Online (Sandbox Code Playgroud)

这演示了如何定义类似的派生枚举;例如混合的 StrEnumstr而不是int.

因此,解决方案是定义一个带有str基类的枚举:

class StatusValues(str, Enum):
    one = "one"
    two = "two"

>>> status = "two"
>>> status == StatusValues.two  # no .value
True
Run Code Online (Sandbox Code Playgroud)

在Python 3.11+中,StrEnum已经包含在enum模块中,但是您提到您仍然需要支持Python 3.7。