一个生成器函数的返回类型提示是什么?

143

我正在尝试为生成器函数编写一个:rtype:类型提示。它返回的是什么类型?

例如,假设我有这个生成器函数,它产生字符串:

def read_text_file(fn):
    """
    Yields the lines of the text file one by one.
    :param fn: Path of text file to read.
    :type fn: str
    :rtype: ???????????????? <======================= what goes here?
    """
    with open(fn, 'rt') as text_file:
        for line in text_file:
            yield line

返回类型不仅仅是字符串,而是一些字符串的可迭代对象?所以我不能只写:rtype: str。正确的提示是什么?


返回一个包含字符串的生成器。 - Panagiotis Simakis
2
看起来你不是在请求类型提示,而是要插入 :rtype: 的文档字符串。 - Moses Koledoye
1
人们甚至没有阅读问题就标记为重复。叹气... - Wood
1
@Jean-FrançoisCorbett 另一个问题要求类型注释。而这个问题则是要求在 :rtype: 中插入文档字符串。它们是不同的事情。 - Wood
请注意,(目前)Sphinx能够从相应的类型提示中自动提取返回类型(rtype)... - OrenIshShalom
显示剩余3条评论
3个回答

156

生成器

Generator[str, None, None]Iterator[str]


7
现在Python 3.9支持更复杂的类型提示,是否会有新的答案? - Nathan Dai
@NathanDai 在Python 3.9中,语法基本相同,只需从collections.abc导入Generator类即可。有关详细信息,请参见我的答案 - Eugene Yarmash
1
此外,从Python 3.9开始,typing.Generator被弃用,建议使用collections.abc.Generator - 101

87

从Python 3.9开始,你可以使用来自collections.abcGenerator[YieldType, SendType, ReturnType]泛型类型注释一个生成器。例如:

from collections.abc import Generator

def echo_round() -> Generator[int, float, str]:
    sent = yield 0
    while sent >= 0:
        sent = yield round(sent)
    return 'Done'
在早期版本的Python中,您可以从typing模块导入Generator类。或者,可以使用typing中的Iterable[YieldType]Iterator[YieldType]

1
在使用类型提示的 yield 动作时,IteratorIterable 有什么区别? - Daniel Lavedonio de Lima
2
@DanielLavedoniodeLima 我猜 Iterable 更通用,而 Iterator 表示结果只能被迭代一次。 - Eugene Yarmash
Iterable 提供了一个 __iter__ 方法,该方法返回一个 Iterator。它本质上是一个迭代器对象的工厂。另一方面,Iterator 用于遍历(产生)连续的元素。迭代器会保持当前位置并返回元素。 简而言之,Iterable 给你提供了一个 Iterator,你可以使用它来获取 Iterable 的元素。 - warownia1

9

比较 IteratorGenerator...

文档将 collections.abc.Generator 定义为“实现...send()throw()close() 方法的生成器类的 ABC”。

因此,我使用 collections.abc.Iterator[ReturnType] 来表示“普通”的生成器,并将 collections.abc.Generator 保留给那些我已经实现了 send()/throw()/close() 的情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接