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

Ray*_*ger 5 python duck-typing python-3.10 structural-pattern-matching

我有通过查找属性来检查命名元组数据类_fields的代码:

if hasattr(candidate, '_fields'):
    do_action()
Run Code Online (Sandbox Code Playgroud)

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

Ray*_*ger 5

了解文档

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

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

模拟hasattr()进行鸭子类型

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

这个具体例子

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

match candidate:
   case object(_fields=_):
       do_action()
Run Code Online (Sandbox Code Playgroud)

完整的实例

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

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')
Run Code Online (Sandbox Code Playgroud)

该脚本输出:

Found wheeled object
Run Code Online (Sandbox Code Playgroud)