首页 > 编程问答 >使用与枚举子集的匹配进行详尽匹配

使用与枚举子集的匹配进行详尽匹配

时间:2024-07-29 05:47:28浏览次数:5  
标签:python mypy

给出以下定义:

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

相关文章

  • 如何在Python中添加热键?
    我正在为游戏制作一个机器人,我想在按下热键时调用该函数。我已经尝试了一些解决方案,但效果不佳。这是我的代码:defstart():whileTrue:ifkeyboard.is_pressed('alt+s'):break...defmain():whileTrue:ifkeyboard.is_pr......
  • 在Python中解压文件
    我通读了zipfile文档,但不明白如何解压缩文件,只了解如何压缩文件。如何将zip文件的所有内容解压缩到同一目录中?importzipfilewithzipfile.ZipFile('your_zip_file.zip','r')aszip_ref:zip_ref.extractall('target_directory')将......
  • 如何在Python中从RSA公钥中提取N和E?
    我有一个RSA公钥,看起来像-----BEGINPUBLICKEY-----MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAvm0WYXg6mJc5GOWJ+5jkhtbBOe0gyTlujRER++cvKOxbIdg8So3mV1eASEHxqSnp5lGa8R9Pyxz3iaZpBCBBvDB7Fbbe5koVTmt+K06o96ki1/4NbHGyRVL/x5fFiVuTVfmk+GZNakH5dXDq0fwvJyVmUtGYA......
  • Swagger、Docker、Python-Flask: : https://editor.swagger.io/ 生成服务器 python-fl
    在https://editor.swagger.io/上您可以粘贴一些json/yaml。我正在将此作为JSON进行测试(不要转换为YAML):{"swagger":"2.0","info":{"version":"1.0","title":"OurfirstgeneratedRES......
  • 使用 Matplotlib 的 Python 代码中出现意外的控制流
    Ubuntu22.04上的此Python3.12代码的行为符合预期,除非我按q或ESC键退出。代码如下:importnumpyasnp,matplotlib.pyplotaspltfrompathlibimportPathfromcollectionsimportnamedtuplefromskimage.ioimportimreadfrommatplotlib.widgets......
  • 参考 - Python 类型提示
    这是什么?这是与在Python中使用类型提示主题相关的问题和答案的集合。这个问题本身就是一个社区维基;欢迎大家参与维护。这是为什么?Python类型提示是一个不断增长的话题,因此许多(可能的)新问题已经被提出,其中许多甚至已经有了答案。该集合有助于查找现有内容。范......
  • 我的 Python 程序中解决 UVa 860 的运行时错误 - 熵文本分析器
    我正在尝试为UVa860编写一个解决方案,但是当我通过vJudge发送它时,它一直显示“运行时错误”。fromsysimportstdinimportmathdefmain():end_of_input=Falselambda_words=0dictionary={}text_entropy=0relative_entropy=0whilenotend_of_in......
  • Python进度条
    当我的脚本正在执行某些可能需要时间的任务时,如何使用进度条?例如,一个需要一些时间才能完成并在完成后返回True的函数。如何在函数执行期间显示进度条?请注意,我需要实时显示进度条,所以我不知道该怎么办。我需要thread为此吗?我不知道。现在在执行函数......
  • 此 Python 代码给出了超出时间限制的错误。由于其中使用的输入或输出方法而在其中传递
    N=int(input())L1=input()L=L1.split()s=set(L)d={}foreins:d[e]=L.count(e)print(d)max_value=max(d.values())print(max_value)L=list(d.values())print(L)res=L.count(max_value)print(res)/在提供正常输入时,它运行良好,但在提......
  • @staticmethod 在 Python 中意味着什么?
    我正在使用Python学习OOP。我想知道@staticmethod在OOP中到底做了什么。为什么我应该/不应该使用它?classCar:@staticmethoddefstart():print("carstarted")defstop():print("carstopped")当然,让我们来分解一下Pyth......