给出以下定义:
class MyEnum(IntEnum):
a = 1
b = 2
c = 3
d = 4
我正在寻找一个替换
SomeExpression
的表达式,它将静态断言值
myEnum
是该分支中的
MyEnum.c | MyEnum.d
– 这样底部的“从不”情况就正确了推断类型
never
– 当然,会确保在运行时采用正确的分支,以便将“匹配”输出到控制台。
def check(myEnum: MyEnum):
match myEnum:
case SomeExpression:
print("matched")
case MyEnum.a:
pass
case MyEnum.b:
pass
case never:
assert_never(never)
在 python 中是否有这样的方法来实现这一点?我尝试过使用更简单的方法,例如匹配中的谓词,它不会根据需要静态地缩小类型。我也调查过
__class_getitem__
但未能使其按预期工作。
遗憾的是,在 Python 中没有直接使用枚举子集进行匹配的方法,以实现你所期望的静态类型缩小和详尽检查。
尽管
__class_getitem__
可以用于创建枚举的类级别子集,但这并不能被静态类型检查器识别为模式匹配的有效案例。
不过,我们可以使用一些替代方案来达到类似的效果:
1. 使用多个
case
语句:
from enum import IntEnum
from typing import NoReturn
class MyEnum(IntEnum):
a = 1
b = 2
c = 3
d = 4
def assert_never(value: NoReturn) -> NoReturn:
raise AssertionError(f"Unexpected value: {value}")
def check(myEnum: MyEnum):
match myEnum:
case MyEnum.c | MyEnum.d:
print("matched")
case MyEnum.a:
pass
case MyEnum.b:
pass
case _:
assert_never(myEnum)
这个方案最接近你的需求,它使用多个
case
语句来匹配
MyEnum.c
和
MyEnum.d
,并提供其他分支来处理剩余的枚举成员。
assert_never
函数用来确保详尽性检查,并在运行时捕获意外情况。
2. 使用 if 语句进行额外的检查:
def check(myEnum: MyEnum):
if myEnum in (MyEnum.c, MyEnum.d):
print("matched")
elif myEnum == MyEnum.a:
pass
elif myEnum == MyEnum.b:
pass
else:
assert_never(myEnum)
这个方案使用
if
语句和成员测试来检查枚举值是否在
(MyEnum.c, MyEnum.d)
中,并提供其他分支来处理剩余的枚举成员。
虽然这些方案无法像你期望的那样直接使用枚举子集进行模式匹配,但它们提供了有效的替代方案,并保持了代码的清晰性和可读性。
标签:python,mypy From: 78804882