簡體   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