繁体   English   中英

如何确定python中任何生成器的产量/发送/返回值

[英]How to determine the yield / send / return values for any generator in python

查看以下内容: https : //docs.python.org/3/library/typing.html#typing.Generator

我不确定如何知道任何给定生成器的收益/发送/返回值是多少?

yield值似乎很简单,因为我认为可以只执行type(next(<generator>)) ,但其他人则不太清楚。

例子

例如,我不确定如何键入以下内容:

# note - this is not meant to be useful...

import pathlib

def list_of_paths(paths) -> list[pathlib.Path]:
    return list(paths)

path_list = list_of_paths(paths = pathlib.Path('.').glob('*'))

如何知道在Generator使用什么?


from typing import Generator
import pathlib

def list_of_paths(paths : Generator[pathlib.Path, ? , ? ]) -> list[pathlib.Path]:
    return list(paths)

path_list = list_of_paths(paths = pathlib.Path('.').glob('*'))

编辑

继续以pathlib.Path.glob ,文档是https://docs.python.org/3/library/pathlib.html#pathlib.Path.glob

请注意,此处清楚此生成器的send / return类型是什么。

老实说,我很少使用Generator 如果您输入提示并且只关心产量值(我发现通常是这种情况),只需使用Iterator 生成器是一个带有额外内容的迭代器,所以这是一个有效的提示。 在这种情况下,您只需使用:

def list_of_paths(paths: Iterator[pathlib.Path]) -> list[pathlib.Path]:
    return list(paths)

不过,要尝试从字面上回答这个问题,您需要深入研究函数的源代码/文档,并尝试推断类型是什么。 特别是对于glob ,如果我将其加载到 Pycharm 中:

import pathlib

p = pathlib.Path()
x = p.glob()

如果我将鼠标悬停在x并按ctrl + shift + p (默认情况下),我会得到一个显示Generator[Path, None, None]的小对话框,这是 Pycharm 的推断。

另外,如果我将鼠标悬停在glob并按ctrl + b ,我会被带到glob的来源,即:

def glob(self, pattern):
    sys.audit("pathlib.Path.glob", self, pattern)
    if not pattern:
        raise ValueError("Unacceptable pattern: {!r}".format(pattern))
    drv, root, pattern_parts = self._flavour.parse_parts((pattern,))
    if drv or root:
        raise NotImplementedError("Non-relative patterns are unsupported")
    selector = _make_selector(tuple(pattern_parts), self._flavour)
    for p in selector.select_from(self):
        yield p

从中,我可以看出它不接收或return任何值,因此这两个值都必须是None 所以基本上,如果你想填写这些字段,你要么依赖文档,一个像 Pycharm 这样好的静态分析工具,要么检查源代码并自己推断。

generator运行时类型实现了两个相关但独立的概念:

generator实现两者的原因是“简单生成器”可以仅实现为“生成器协程”,该协程用其值回复空消息。

因此, typing.Generator也代表了这两个概念:

  • Generator[YieldType, SendType, ReturnType]编码“生成器协程”,并且
  • Generator[YieldType, None, None]编码“简单的生成器”。

所以仅仅因为遇到一个generatortyping.Generator generator并不意味着有发送和返回类型。


除非另有明确说明,否则假设“生成器”意味着“简单生成器”通常是可行的。 Python 术语表:生成器仅描述“简单生成器”类型,而Python 术语表:协程指的是async函数——裸的“生成器协程”在 Python 使用中非常罕见。

给定类似于pathlib.Path.glob的描述,它说“产生所有匹配的文件”并且从未提及发送或返回值,假设一个处理“简单生成器”是安全的。

如有疑问,请使用MyPy 的reveal_type来显示表达式的静态类型:

$ mypy -c "from pathlib import Path; reveal_type(Path('.').glob('x'))"
<string>:1: note: Revealed type is 'typing.Generator[pathlib.Path*, None, None]'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM