【问题标题】:How to tell which type annotations support __iter__如何判断哪些类型注解支持 __iter__
【发布时间】:2021-05-18 17:21:17
【问题描述】:

如果我解析 Python 文件的 ast 并看到变量具有类型注释,例如Mapping,如何判断该注解是否支持__iter__

一种选择是查看https://mypy.readthedocs.io/en/stable/protocols.html,列出支持__iter__的所有内容(例如IterableIteratorCollection、...),并检查给定变量的注释是否在那个列表中。

但是,这感觉很脆弱 - 有没有更好的方法?我需要能够通过从它的 ast 中解析变量的注释来做到这一点 - 在变量上运行 iter 不是一种选择。

【问题讨论】:

  • 一个类型可以支持__iter__,而无需指定类型注释。例如,Mapping 并不暗示迭代,但也不排除它。为什么需要依赖注解?
  • 因为这是一个静态分析工具
  • 您可能做的最好的事情是检查提示是否是collections.abc.Iterable 的子类,只要它是collectors.abc 中的其他标准类型之一,这应该是正确的,但可能不是符合某人的自定义协议。
  • (实际上,Mapping 确实 意味着迭代,因为它是Collection 的子类,它是Iterable 的子类。对不起,我的错误。)
  • 因为它不是Iterable实例isinstance(int, int) 也返回 False。请改用issubclass()。 (typing.Iterable 只是 `collections.abc.Iterable 的别名,通过某种包装器。)

标签: python iterator abstract-syntax-tree mypy python-typing


【解决方案1】:

最简单的方法是解析给定注解的 FQN,然后检索它所属模块的存根(例如,来自 typeshed 的 typing.pyi),然后递归解密该类实现的所有方法并检查它是否实现您希望它执行的协议。显然这是一个复杂的过程,所以如果你想让事情变得更容易而不是解析和部分评估模块存根,你可以尝试动态导入模块,然后做一个简单的issubclass 检查。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-30
    • 2017-10-24
    • 2018-12-14
    • 2011-06-10
    • 1970-01-01
    相关资源
    最近更新 更多