파이썬 (`next`없이) 반복 가능한 생성기를 부분적으로 소비하는 방법은 무엇입니까?

Nov 15 2020

반복 가능한 생성기 역할을하는 클래스가 있는데 ( 파이썬 생성기에서 '반환'값을받는 가장 좋은 방법에 따라 ) for루프 를 사용하여 부분적으로 사용하고 싶습니다 .

첫 번째 부분 소비는 반복기 만 사용하는 라이브러리를 사용하기 때문에 사용할 수 없습니다 next(예 : Python-다양한 소비자 내부에서 하나의 생성기 사용). 라이브러리 기능이 중단 된 지점부터 생성기를 계속 사용하려면 어떻게해야합니까?

(관련 : 파이썬 발전기를 일시 정지 , 중단 된 후 소비가 나중에 다시 시작하는 방법은 '일시 정지'에 있는가 또는 부분적으로 파이썬에서 발전기를 소비? )

class gen(): # https://stackoverflow.com/q/34073370
    def __iter__(self):
        for i in range(20):
            yield i

# I want to partially consume in the first loop and finish in the second
my_gen_2 = gen()
for i in my_gen_2:  # imagine this is the internal implementation of the library function
    print(i)
    if i > 10:      # the real break condition is when iterfzf recieves user input
        break

for i in my_gen_2:  # i'd like to process the remaining elements instead of starting over
    print('p2', i)

# the confusion boils down to this
my_gen = gen()
for i in my_gen:
    print(i)    # prints 1 through 20 as expected
for i in my_gen:
    print('part two', i)    # prints something, even though the generator should have been "consumed"?

답변

2 napuzba Nov 15 2020 at 02:36

루프에서 생성기를 반복 할 때마다 새 반복자를 얻습니다. 예를 들면 :

class gen(): # https://stackoverflow.com/q/34073370
    def __init__(self):
        self.count = 0
    def __iter__(self):
        self.count += 1
        print("Hallo iter {0}".format(self.count))
        yield self.count


my_gen = gen()
>>> for i in my_gen:
...    pass
Hallo iter 1
>>> for i in my_gen:
...    pass
Hallo iter 2

이전 반복자를 사용하려면 다음과 같이 작업하십시오. gen().__iter__()

>>> my_gen = gen().__iter__()
>>> for i in my_gen:
...    pass
Hallo iter 1
>>> for i in my_gen:
...    pass
Exr0n Nov 15 2020 at 02:44

@napuzba가 지적했듯이 __iter__사용할 때마다 완전히 새로운 생성기를 반환합니다. 대신 상태를 self다음 위치에 저장하십시오 .

class gen():
    def __init__(self):
        self.count = 0
    def __iter__(self):
        while self.count < 20:
            self.count += 1
            yield self.count