如何在 Python 3.10 中使用要匹配的类型进行结构模式匹配?

问题描述 投票:0回答:3

我正在尝试使用控制台匹配 Python 3.10 中的类型:

t = 12.0
match type(t):
  case int:
    print("int")
  case float:
    print("float")

我得到这个错误:

  File "<stdin>", line 2
SyntaxError: name capture 'int' makes remaining patterns unreachable

我该如何解决这个问题?

types pattern-matching python-3.10
3个回答
10
投票

丢掉

type()
并为您的类型添加括号:

t = 12.0
match t:
  case int():
    print("int")
  case float():
    print("float")

我不确定为什么你写的东西不起作用,但这个有效。


0
投票

我的修复是:

match type(t):
  case v if v is int:
    print("int")
  case v if v is float:
    print("float")

它不是很优雅,但它是我能用模式匹配做的最好的。


0
投票

这是新语法的一个常见“陷阱”:case 子句不是表达式。也就是说,如果您将变量名放在 case 子句中,则语法 assigns to 该名称而不是 reading 该名称。

t = 12.0
match t:
    case newvar: # This is equal to `newvar = t`
        print(f"bound a new variable called newvar: {newvar})
        # prints "bound a new variable called newvar: 12.00000000"
    case 13.0:
        print("found 13.0")
    case [*_]:
        print("found some sort of iterable")
    case _:
        print("no match")

So we can recast your OP like so:

t = 12.0 tt = type(t) # 明显浮动 匹配tt: case int: # 赋值给 int!

tt = int
,覆盖内置 print(f"int 的值:{int}") # 结果:“整数的值:” # 现在你必须做
from builtins import int as int2
来获得类型。 case float: # 分配给 float,在这种情况下是空操作
float = float
# 事实上,这个子句与前面的子句相同:匹配一个变量并将其绑定到它的新名称 case float(): # 因为这不是变量名,所以不会发生赋值。 # 在引擎盖下,这等同于
isinstance
检查。 #
float
不是它自己的一个实例,所以这不匹配。 print(f"tt: {tt} 是 float 的一个实例") # 从不打印

坦率地说,我不完全确定引擎盖下的实例检查是如何工作的,但它肯定像另一个答案所说的那样工作:根据语法的定义,类型检查是这样完成的:

match instance:
    case type():
        print(f"object {instance} is of type {type}!")

所以我们回到开始的地方:case 子句不是表达式。正如 PEP 中提到的,最好将 case 子句视为一种类似于函数声明的方式,我们在其中为函数命名参数,并可能将一些默认值绑定到那些新命名的参数。但是我们从来没有,从来没有read case 子句中的现有变量,只创建新变量。还涉及一些其他的微妙之处,例如点访问不能算作这个目的的“变量”,但这已经很复杂了,我会把它留在这里。

© www.soinside.com 2019 - 2024. All rights reserved.