如何使用结构模式匹配来表达 hasattr() 鸭子类型逻辑?

问题描述

我有通过查找 _fields 属性来检查 named tuplesdataclasses代码

if hasattr(candidate,'_fields'):
    do_action()

如何使用 Python 3.10 的匹配/大小写结构模式匹配来表达这一点?

解决方法

了解文档

PEP 634 用于结构模式匹配将此功能记录为 class pattern

  • 编写 cls() 将进行 isinstance() 测试。
  • 添加关键字模式 cls(attr=variable) 测试属性是否存在并将值绑定到变量。

模拟 hasattr()duck typing

  • cls 设置为 object 以便任何类都可以匹配。
  • attr 设置为 _fields,即必须存在的属性。
  • 如果您不需要捕获值,请将 variable 设置为 _;如果您想捕获该值,请将其设置为其他变量名称。

这个具体例子

您的具体示例 if hasattr(candidate,'_fields'): do_action() 转换为:

match candidate:
   case object(_fields=_):
       do_action()

完整的示例

这显示了所有部件是如何组合在一起的:

from typing import NamedTuple
from dataclasses import dataclass

class Whale(NamedTuple):
    name: str
    num_fins: int

@dataclass
class Vehicle:
    name: str
    num_wheels: int

subject = Vehicle('bicycle',2)
    
match subject:
    case object(num_fins=n):
        print(f'Found {n} fins')
    case object(num_wheels=_):
        print(f'Found wheeled object')
    case _:
        print('Unknown')

此脚本输出:

Found wheeled object