【问题标题】:Python what is the correct typing for any iterable that also exposes len()? [duplicate]Python 对于任何也暴露 len() 的可迭代对象,正确的类型是什么? [复制]
【发布时间】:2019-08-24 13:01:18
【问题描述】:

我有一个函数适用于任何可以返回其长度的迭代。 所以它适用于 list、dict 和 dict.tems(),即ItemsView

我应该使用什么正确的打字方式?

编辑: 这是一个示例函数:

def print_iter(some_iterable: xxx):
    for idx, val in enumerate(some_iterable):
        print(val, idx, len(some_iterable))

我不确定要使用什么类型来代替 xxx

【问题讨论】:

  • 请注意,建议的副本(当前)投票最高的答案不是您想要的;请参阅answer using Protocol,或我在下面的答案。
  • @che 因为 Collection 还必须有 __contains__? / 您可以在该答案上留下评论,而不是在这里。
  • 其实我收回我的评论;我记错了Collection 的用途。但__contains__ 可能确实比您需要的更具体。

标签: python python-3.x typing


【解决方案1】:

您需要导入typing_extensions 模块并定义一个新的Protocol 子类。

from typing_extensions import Protocol


class SupportsLen(Protocol):
    def __len__(self) -> int:
        return 0  # Exact value unimportant; this is for the type checker only.


def print_iter(some_iterable: SupportsLen):
    for idx, val in enumerate(some_iterable):
        print(val, idx, len(some_iterable))

(为了完整起见,SupportsLen 可能还应该定义您需要的任何内容,以使其真正可迭代。)

【讨论】:

  • 我们可以从typing.Iterable继承并添加我们的附加功能,即__len__
  • 我不确定。我不知道是什么使Protocol 与需要提供的普通抽象基类不同。
  • 好的,我自己研究一下。
  • @VaibhavVishal Protocol 使用“结构子类型”,因此您无需声明每个类都“实现”相关类型,只需要声明相关成员即可。由于某种原因,原始类型提示 pep 484 带有更接近 C++/Java 的名义子类型,但似乎与 Python 的鸭子类型不太兼容
  • @VaibhavVishal 这是一个非常大的话题,我认为这里的一些 cmets 不会有太大帮助......维基百科页面(12)包含概述和参考@ 987654324@ 如果您对这类事情感兴趣,我会推荐它。原来c2 wiki也有很好的总结
猜你喜欢
  • 2016-02-15
  • 2018-03-16
  • 2018-06-19
  • 2022-01-19
  • 2020-10-02
  • 2018-08-19
  • 2021-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多