gpt4 book ai didi

python-3.x - Mypy 迭代器和生成器有什么区别?

转载 作者:行者123 更新时间:2023-12-03 23:11:38 25 4
gpt4 key购买 nike

主要区别是什么,每个应该使用什么以及在哪里使用?

例如,在这个例子中使用 - 和 Iterator 和 Generator 对我来说似乎很合适......但它是真的吗?

迭代器

from typing import Generator, Iterator

def fib(n: int) -> Iterator[int]:
a :int = 0
b :int = 1
while a < n:
yield a
a, b = b, a+b

print([x for x in fib(3)])

发电机

from typing import Generator 

def fib(n: int) -> Generator[int, None, None]:
a :int = 0
b :int = 1
while a < n:
yield a
a, b = b, a+b

print([x for x in fib(3)])

最佳答案

每当您不确定某些内置类型到底是什么时,我建议检查 Typeshed ,Python 标准库(以及一些选择的第 3 方模块)的类型提示存储库。 Mypy 在每个版本中都包含一个 typeshed 版本。

例如,here are the definitions迭代器和生成器到底是什么:

@runtime
class Iterator(Iterable[_T_co], Protocol[_T_co]):
@abstractmethod
def __next__(self) -> _T_co: ...
def __iter__(self) -> Iterator[_T_co]: ...

class Generator(Iterator[_T_co], Generic[_T_co, _T_contra, _V_co]):
@abstractmethod
def __next__(self) -> _T_co: ...

@abstractmethod
def send(self, value: _T_contra) -> _T_co: ...

@abstractmethod
def throw(self, typ: Type[BaseException], val: Optional[BaseException] = ...,
tb: Optional[TracebackType] = ...) -> _T_co: ...

@abstractmethod
def close(self) -> None: ...

@abstractmethod
def __iter__(self) -> Generator[_T_co, _T_contra, _V_co]: ...

@property
def gi_code(self) -> CodeType: ...
@property
def gi_frame(self) -> FrameType: ...
@property
def gi_running(self) -> bool: ...
@property
def gi_yieldfrom(self) -> Optional[Generator]: ...

请注意:
  • 迭代器只有两种方法:__next____iter__但是生成器还有更多。
  • 生成器是迭代器的子类型——每一个生成器也是迭代器,但反之则不然。

  • 但这在高层次上意味着什么?

    嗯,简而言之,使用迭代器,信息流是单向的。当你有一个迭代器时,你真正能做的就是调用 __next__方法来获得下一个要产生的值。

    相比之下,生成器的信息流是双向的:您可以通过 send 将信息发送回生成器。方法。

    实际上,这就是其他两个类型参数的用途——当您执行 Generator[A, B, C] 时,你说你产生的值是类型 A ,您发送到生成器的值的类型为 B ,并且您从生成器返回的值的类型为 C .

    以下是一些额外的有用阅读 Material :
  • python generator "send" function purpose?
  • Difference between Python's Generators and Iterators
  • Return in generator together with yield in Python 3.3
  • https://jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/


  • 那么,什么时候应该使用迭代器和生成器呢?

    好吧,一般来说,您应该倾向于使用有助于调用者理解您期望如何使用返回值的类型。

    例如,将您的 fib例子。你所做的只是产生值:信息流是单向的,并且代码并没有真正设置为接受来自调用者的信息。

    因此,在这种情况下使用 Iterator 而不是 Generator 是最容易理解的:Iterator 最能反射(reflect) fib 实现的单向性。

    (如果您编写了一个数据流是双向的生成器,那么您当然需要使用生成器而不是迭代器。)

    关于python-3.x - Mypy 迭代器和生成器有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56544823/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com