Python 我们可以使用类实现生成器吗?
当我们查看Python文档时,我们可以看到生成器总是使用yield语句定义的,但是在Internet上,我们可以看到一些人试图使用类实现生成器(例如,这里) 下面是使用类的示例生成器实现:Python 我们可以使用类实现生成器吗?,python,python-3.x,generator,Python,Python 3.x,Generator,当我们查看Python文档时,我们可以看到生成器总是使用yield语句定义的,但是在Internet上,我们可以看到一些人试图使用类实现生成器(例如,这里) 下面是使用类的示例生成器实现: from collections import Generator class Fib(Generator): def __init__(self): self.a, self.b = 0, 1 def send(self, ignored_arg):
from collections import Generator
class Fib(Generator):
def __init__(self):
self.a, self.b = 0, 1
def send(self, ignored_arg):
return_value = self.a
self.a, self.b = self.b, self.a+self.b
return return_value
def throw(self, type=None, value=None, traceback=None):
raise StopIteration
当我们在repl中执行它时,我们可以看到它不是生成器,而是普通对象。它只是试图表现得像发电机
>>> x = Fib()
>>> x
<__main__.Fib object at 0x7f05a61eab70>
>x=Fib()
>>>x
当我们看PEP 342时:
我错了吗?使用类实现真正的生成器真的有可能吗?生成器只是一种迭代器。从: 发电机功能
使用
yield
语句[…]的函数或方法称为生成器函数。这样的函数在调用时,总是返回一个迭代器对象,该对象可用于执行函数体:调用迭代器的迭代器。\uuuu next\uu()
方法将导致函数执行,直到它使用yield
语句提供值为止。当函数执行return语句或结束时,将引发StopIteration
异常,迭代器将到达要返回的值集的末尾
您无法通过repr()
输出判断某个东西是否是发电机。Python寻找方法,您可以在这些方法之上实现自己的send
和throw
方法,正如您所做的那样
因此,您的实现按设计工作,它是有效的迭代器:
>>> x = Fib()
>>> next(x)
0
>>> next(x)
1
如果没有collections.abc.Generator
基,您也可以实现自己的(这必须返回self
),以及在调用时生成下一个值或在完成时引发StopIteration
的
基本的
collections.abc.Generator
实现为您定义了\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法,该方法只调用self.send(None)
。您打印了一个对象。问题是如何使用协同程序object@cricket_007:不,不是。@cricket\u 007:Coroutines也有下面列出的方法,类似于生成器的方法。@Adam:这是一个哲学问题。一个对象拥有与列表相同的所有方法,真的是列表吗?Python不在乎;只要其他代码可以像使用生成器一样使用它,一切都很好。不,它不是一个生成器,但它像一个生成器一样行走和说话。@Adam:thecollections.abc
对象有两个功能:让您创建像这些类型那样行走和说话的对象,以及测试这些类型是否正确。如果您的目标是生成一个可以替代生成器的对象,那么使用collections.abc.generator
作为基础是一种很好的方法。