Python 我们可以使用类实现生成器吗?

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):

当我们查看Python文档时,我们可以看到生成器总是使用yield语句定义的,但是在Internet上,我们可以看到一些人试图使用类实现生成器(例如,这里)

下面是使用类的示例生成器实现:

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时:

  • 为生成器迭代器添加close()方法,该方法在生成器暂停时引发GeneratorExit
  • 我认为使用自己的类实现是不可能满足这个条件的


    我错了吗?使用类实现真正的生成器真的有可能吗?

    生成器只是一种迭代器。从:

    发电机功能
    使用
    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:the
    collections.abc
    对象有两个功能:让您创建像这些类型那样行走和说话的对象,以及测试这些类型是否正确。如果您的目标是生成一个可以替代生成器的对象,那么使用
    collections.abc.generator
    作为基础是一种很好的方法。