类型提示与鸭子类型

dzi*_*iou 3 python type-hinting

在 Python 中使用类型提示的缺点之一是交易 Python 代码的美。

在类型提示之前,我的方法签名很简洁:

def echo(items):
    for i in items:
        print(i)
    
Run Code Online (Sandbox Code Playgroud)

由于我的团队正在使用类型提示,我也在我的代码中添加了类型提示:

def echo(items: Set[str]) -> None:
Run Code Online (Sandbox Code Playgroud)

还是蛮清晰的。一段时间后,我的代码中对集合进行操作的其他部分要求我items是可散列的,而其他部分则不需要。所以我决定也支持frozenset,现在我的方法看起来像:

 def echo(items: Union[Set[str],Frozenset[str]]) -> None:
 
Run Code Online (Sandbox Code Playgroud)

它开始看起来像 Java 中的方法,尽管在 Java 中我可以对接口进行操作,而忽略实现细节:

 void echo(Set<String> items) {
Run Code Online (Sandbox Code Playgroud)

Python 不支持接口概念,即我不能声明Set实现Frozenset. 最初的实现将两个工作Set,并Frozenset感谢鸭打字:既表现为一套。然而,我的印象是显式类型提示在某种程度上与鸭子类型不兼容

如何在打字提示和鸭子打字之间找到良好的平衡?

che*_*ner 6

使用AbstractSet

from typing import AbstractSet

def echo(items: AbstractSet[str]) -> None:
    ...
Run Code Online (Sandbox Code Playgroud)

SetFrozenSet继承(直接或间接)从AbstractSet

AbstractSet
    |
    |
    +--------------+
    |              |
    |              |
MutableSet        FrozenSet
    |
    |
   Set
Run Code Online (Sandbox Code Playgroud)