You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否使用Structural Pattern Matching实现类型收窄?

问题描述

借助PEP 622的结构化模式匹配(SPM)功能,我希望避免将egg以Mapping类型传入multiple函数,即通过SPM实现类型收窄。

根据PEP文档说明:

通配符_可添加星号以匹配任意长度的序列。例如:

  • [*_]匹配任意长度的序列。

我编写了如下代码:

# egg 的类型为 typing.Sequence[typing.Mapping[str, typing.Any]] | typing.Mapping[str, typing.Any]
match egg:
    case [*_]:
        print(multiple(egg))
    case _:
        print(single(egg))

我原本认为,case [*_]分支中egg会被视为Sequence类型,case _分支中则为非Sequence类型。但运行mypy检查项目时出现如下错误:

file.py:19: error: Argument 1 to "multiple" has incompatible type "Union[Sequence[Mapping[str, Any]], Mapping[str, Any]]"; expected "Sequence[Mapping[str, Any]]"  [arg-type]
file.py:21: error: Argument 1 to "single" has incompatible type "Union[Sequence[Mapping[str, Any]], Mapping[str, Any]]"; expected "Mapping[str, Any]"  [arg-type]
Found 2 errors in 1 file (checked 1 source file)

以下是触发该mypy错误的最小可复现示例:

import typing

SingleExecuteParams = typing.Mapping[str, typing.Any]
MultiExecuteParams = typing.Sequence[SingleExecuteParams]
AnyExecuteParams = MultiExecuteParams | SingleExecuteParams


def multiple(spam: MultiExecuteParams) -> int:
    return 1


def single(spam: SingleExecuteParams) -> int:
    return 1


def main(egg: AnyExecuteParams) -> None:
    match egg:
        case [*_]:
            print(multiple(egg))
        case _:
            print(single(egg))
已尝试的方案

使用case {}:

根据文档说明,映射模式中case {}:会匹配collections.abc.Mapping的实例,额外键会被忽略(且{**_}是无效写法),但替换后问题依旧。

匹配对象必须是collections.abc.Mapping的实例。即使未指定rest,对象中的额外键也会被忽略。这与序列模式不同,序列模式中额外元素会导致匹配失败。但映射与序列存在本质差异:它们具有自然的结构子类型行为,即传递带有额外键的字典通常可以正常工作。因此,映射模式中_是无效的;它始终是无操作的,移除后不会产生任何影响。

使用case ... if ...语法

用case _ if isinstance(egg, typing.Sequence):可以实现类型收窄,但这样就失去了使用SPM原生模式匹配的意义。

对比:if语句实现类型收窄

使用普通if语句时,mypy不会触发错误:

def main(egg: AnyExecuteParams) -> None:
    if isinstance(egg, collections.abc.Sequence):
        print(multiple(egg))
    else:
        print(single(egg))

根据PEP文档中的匹配语义说明:

本质上,这等效于一串if ... elif ... else语句。

我认为两种写法应该是等价的,但实际mypy对SPM的处理却不一致。


内容的提问来源于stack exchange,提问作者Dorian Turba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 22:30:33