繁体   English   中英

消耗的Python生成器的不同行为取决于实现

[英]Different behavior of consumed Python generators depending on implementation

考虑下面的代码示例。 我定义了生成器的两种实现,生成器生成数字0、1、2。我的期望是SimpleClass()。classgen的行为与mygen相同。 我知道,生成器只能使用一次。 这意味着一个迭代器只能迭代一次。

class SimpleClass(object):
    @property
    def classgen(self):
        for i in range(3):
            yield i

mygen = (p for p in range(3))


##### Test behavior
sc = SimpleClass()
print(type(sc.classgen))
print(type(mygen))
print("")

print("Iterating over new sc.classgen")
for i in sc.classgen:
    print(i)
print("")

print("Iterating over consumed sc.classgen")
for i in sc.classgen:
    print(i)
print("")


print("Iterating over new mygen")
for i in mygen:
    print(i)
print("")

print("Iterating over consumed mygen")
for i in mygen:
    print(i)

我的期望是在每个生成器上进行的第一次迭代都会打印数字0、1、2,实际上就是这样。 但是我希望当我第二次遍历每个生成器时,不会看到任何打印。 对于mygen的第二个循环确实如此,但是在sc.classgen上的第二个循环仍然显示数字0、1、2。我无法解释为什么会这样。 我以为发电机只能使用一次?

这是因为您没有调用同一个生成器,所以如果将sc.classgen分配给变量,它将表现出预期的效果。

class SimpleClass(object):
    @property
    def classgen(self):
        for i in range(3):
            yield i

mygen = (p for p in range(3))


##### Test behavior
sc = SimpleClass()
print(type(sc.classgen))
print(type(mygen))
print("")

g = sc.classgen

print("Iterating over new sc.classgen")
for i in g:
    print(i)
print("")

print("Iterating over consumed sc.classgen")
for i in g:
    print(i)
print("")


print("Iterating over new mygen")
for i in mygen:
    print(i)
print("")

print("Iterating over consumed mygen")
for i in mygen:
    print(i)

由于classgen属性是一个函数,因此每次访问它都会创建一个新属性。

@property不缓存该方法的返回值,因此,每次调用sc.classgen时,您将使用不同的生成器。 您可以对此进行测试:

import time


class SimpleClass(object):
    @property
    def the_time(self):
        return time.time()


sc = SimpleClass()

time1 = sc.the_time
time.sleep(2)
time2 = sc.the_time

print(time1 == time2)
> False

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM