如何使用python的结构模式匹配来测试内置类型?

Cur*_*984 9 python python-3.10 structural-pattern-matching

我正在尝试使用 SPM 来确定某种类型intan 还是str.

下面的代码:

from typing import Type

def main(type_to_match: Type):
    match type_to_match:
        case str():
            print("This is a String")
        case int():
            print("This is an Int")
        case _:
            print("\nhttps://en.meming.world/images/en/0/03/I%27ve_Never_Met_This_Man_In_My_Life.jpg")

if __name__ == "__main__":
    test_type = str
    main(test_type)
Run Code Online (Sandbox Code Playgroud)

返回https://en.meming.world/images/en/0/03/I%27ve_Never_Met_This_Man_In_My_Life.jpg

我找到的大多数文档都讨论了如何测试某个变量是否是某个类型的实例。但不是如何测试类型是否属于某种类型。

关于如何使其发挥作用有什么想法吗?

Pat*_*ski 13

如果您只是直接传递类型,它会认为它是“名称捕获”而不是“值捕获”。builtins您可以通过导入模块并使用点符号检查类型来强制它使用值捕获。

import builtins
from typing import Type


def main(type_: Type):
    match (type_):
        case builtins.str:  # it works with the dotted notation
            print(f"{type_} is a String")
        case builtins.int:
            print(f"{type_} is an Int")
        case _:
            print("\nhttps://en.meming.world/images/en/0/03/I%27ve_Never_Met_This_Man_In_My_Life.jpg")

if __name__ == "__main__":
    main(type("hello"))  # <class 'str'> is a String
    main(str)  # <class 'str'> is a String
    main(type(42))  # <class 'int'> is an Int
    main(int)  # <class 'int'> is an Int
Run Code Online (Sandbox Code Playgroud)

  • @jsbueno 那是行不通的。请参阅 /sf/ask/4631160271/。使用裸名称意味着捕获的名称。如果你想使用名称作为常量,它必须是点符号...... (10认同)
  • @jsbueno `case str` 给出 `SyntaxError:名称捕获 'str' 使剩余模式无法访问`。如果您有一个实际的工作示例,我很乐意看到。 (3认同)

Tom*_*koo 6

顾名思义,结构模式匹配更适合匹配模式,而不是值(就像其他语言中的经典switch/case)。例如,它使得检查列表或字典的不同可能结构变得非常容易,但对于值而言,与简单结构相比并没有太大优势if/else

if type_to_match == str:
    print("This is a String")
elif type_to_match == int:
    print("This is an Int")
else:
    print("\nhttps://en.meming.world/images/en/0/03/I%27ve_Never_Met_This_Man_In_My_Life.jpg")
Run Code Online (Sandbox Code Playgroud)

但如果你真的想使用 SPM,你可以使用防护功能issublcass检查一个类型是否是任何其他类型的子类型:

match type_to_match:
    case s if issubclass(type_to_match, str):
        print(f"{s} - This is a String")
    case n if issubclass(type_to_match, int):
        print(f"{n} - This is an Int")
    case _:
        print("\nhttps://en.meming.world/images/en/0/03/I%27ve_Never_Met_This_Man_In_My_Life.jpg")
Run Code Online (Sandbox Code Playgroud)