生成器/yield的python实现示例

生成器/yield的python实现示例,python,python-3.x,generator,yield,python-internals,Python,Python 3.x,Generator,Yield,Python Internals,让我们使用以下python代码生成一个无限计数器: def infinite_sequence(): num = 0 while True: yield num num += 1 我可以称之为: for i in infinite_sequence(): print (i) 只要我想退出,就执行一次键盘中断。yield/generator东西是用C/Cpython实现的。在python中实现类似“生成器功能”的示例是什么?也就是说,如果

让我们使用以下python代码生成一个无限计数器:

def infinite_sequence():
    num = 0
    while True:
        yield num
        num += 1
我可以称之为:

for i in infinite_sequence():
    print (i)

只要我想退出,就执行一次键盘中断。
yield/generator
东西是用C/Cpython实现的。在python中实现类似“生成器功能”的示例是什么?也就是说,如果我可以调用一个函数/方法来代替
yield num
行,并获得相同的功能,那么在python中实现该功能的示例是什么呢?

您必须自己实现迭代器协议

class InfiniteSequence:
    def __init__(self):
        self.x = 0

    def __iter__(self):
        return self

    def __next__(self):
        x = self.x
        self.x = x + 1
        return x


for i in InfiniteSequence():
    print(i)
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法必须返回实现
的内容。
\uuuuuuuuuuuuuuuu
方法必须返回序列中的下一个值。实例属性在调用
\uuuuu next\uuuuu
之间保持状态

同一个类不必实现这两种方法。您可能需要一个单独的迭代器类,这样就可以在iterable序列上拥有多个独立的迭代器

class InfiniteSequence:
    def __init__(self, start):
        self.start = start

    def __iter__(self):
        return InfSeqIterator(self.start)


class InfSeqIterator:
    def __init__(self, x):
        self.x = x

    def __iter__(self):
        return self

    def __next__(self):
        x = self.x
        self.x += 1
        return x


nats = InfiniteSequence()

i1 = iter(nats)
i2 = iter(nats)

assert next(i1) == 0
assert next(i2) == 0  # not 1


generator
只是实现此协议的类的一个示例;您可以使用生成器表达式(
(x代表[1,2,3])
)或生成器函数(即使用
yield
)创建
生成器的实例。

您必须自己实现迭代器协议

class InfiniteSequence:
    def __init__(self):
        self.x = 0

    def __iter__(self):
        return self

    def __next__(self):
        x = self.x
        self.x = x + 1
        return x


for i in InfiniteSequence():
    print(i)
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法必须返回实现
的内容。
\uuuuuuuuuuuuuuuu
方法必须返回序列中的下一个值。实例属性在调用
\uuuuu next\uuuuu
之间保持状态

同一个类不必实现这两种方法。您可能需要一个单独的迭代器类,这样就可以在iterable序列上拥有多个独立的迭代器

class InfiniteSequence:
    def __init__(self, start):
        self.start = start

    def __iter__(self):
        return InfSeqIterator(self.start)


class InfSeqIterator:
    def __init__(self, x):
        self.x = x

    def __iter__(self):
        return self

    def __next__(self):
        x = self.x
        self.x += 1
        return x


nats = InfiniteSequence()

i1 = iter(nats)
i2 = iter(nats)

assert next(i1) == 0
assert next(i2) == 0  # not 1


generator
只是实现此协议的类的一个示例;您可以使用生成器表达式(
(x代表[1,2,3])
)或生成器函数(即,使用
产生
的函数)创建
生成器的实例。

python/cpython如何推断
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu下一个方法(或其等效方法)从
yield
语句的上下文来看,这确实是一个检查您感兴趣的任何实现的源代码的问题;这不是Python语言定义的。为什么在递增
self.x
时需要绕道?因为您希望返回
self.x
的当前值,而不是递增的值。您可以通过将
self.x
初始化为小于起始值的值来避免这种情况;然后您可以增加它并返回它。我只是没有。@chepner你能链接到迭代器协议的python部分吗?以下是C版本:。作为旁注,我希望python的文档在搜索中得到更好的表现(无论是在Google还是python搜索本身都非常糟糕)。python/cpython如何推断
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu从
yield
语句的上下文来看,这确实是一个检查您感兴趣的任何实现的源代码的问题;这不是Python语言定义的。为什么在递增
self.x
时需要绕道?因为您希望返回
self.x
的当前值,而不是递增的值。您可以通过将
self.x
初始化为小于起始值的值来避免这种情况;然后您可以增加它并返回它。我只是没有。@chepner你能链接到迭代器协议的python部分吗?以下是C版本:。作为旁注,我希望python的文档在搜索中得到更好的表现(无论是在Google还是python搜索本身都非常糟糕)。