[英]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]
编码“简单的生成器”。 所以仅仅因为遇到一个generator
或typing.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.