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

Posted

技术标签:

【中文标题】如何用结构模式匹配表达 hasattr() 鸭子类型逻辑?【英文标题】:How to express hasattr() duck typing logic with structural pattern matching? 【发布时间】:2021-08-03 23:10:54 【问题描述】:

我的代码通过查找_fields 属性来检查named tuples 和dataclasses:

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

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

【问题讨论】:

【参考方案1】:

了解文档

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

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

要为duck typing 模拟hasattr():

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

【讨论】:

以上是关于如何用结构模式匹配表达 hasattr() 鸭子类型逻辑?的主要内容,如果未能解决你的问题,请参考以下文章

如何用元组列表替换列表中正则表达式匹配的模式?

如何用正则表达式匹配括号中的内容。

如何用grep中的变量实现多个模式?

如何用js匹配url的正则表达式

如何用正则表达式匹配整个单词?

如何用正则表达式在JS中匹配出相应的拓展名?