用于检查协议的模式匹配。获取类型错误:调用的匹配模式必须是类型

Ray*_*ger 3 python iterable abc typeerror structural-pattern-matching

我需要匹配输入可迭代的情况。这是我尝试过的:

from typing import Iterable

def detector(x: Iterable | int | float | None) -> bool:
    match x:
        case Iterable():
            print('Iterable')
            return True
        case _:
            print('Non iterable')
            return False
Run Code Online (Sandbox Code Playgroud)

这会产生这个错误:

TypeError: called match pattern must be a type
Run Code Online (Sandbox Code Playgroud)

是否可以通过匹配/大小写来检测可迭代性?

请注意,这两个问题解决了相同的错误消息,但两个问题都不是关于如何检测可迭代性:

Ray*_*ger 7

问题是types.Iterable仅用于类型提示,并且不被结构模式匹配视为“类型”。相反,您需要使用抽象基类来检测可迭代性:collections.abc.Iterable

解决方案是区分两种情况,将一种标记为类型提示,另一种标记为用于结构模式匹配的类模式:

def detector(x: typing.Iterable | int | float | None) -> bool:
    match x:
        case collections.abc.Iterable():
            print('Iterable')
            return True
        case _:
            print('Non iterable')
            return False
Run Code Online (Sandbox Code Playgroud)

另请注意,在撰写本文时,mypy不支持match语句。