Пример python реализации генератора / доходности - PullRequest
0 голосов
/ 26 февраля 2020

Давайте возьмем следующий код python, чтобы сгенерировать бесконечный счетчик:

def infinite_sequence():
    num = 0
    while True:
        yield num
        num += 1

Затем я могу назвать это следующим образом:

for i in infinite_sequence():
    print (i)

И делать KeyboardInterrupt всякий раз, когда я хочу выйти из него. Материал yield/generator реализован в C / Cpython. Что может быть примером реализации подобной «функциональности генератора» в python? То есть, если бы я мог вызвать функцию / метод вместо строки yield num и получить ту же функциональность, что было бы примером реализации этого в python?

1 Ответ

2 голосов
/ 26 февраля 2020

Вы должны будете реализовать протокол итератора самостоятельно.

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)

Метод __iter__ должен возвращать то, что реализует __next__. Метод __next__ должен возвращать следующее значение в последовательности. Атрибут экземпляра поддерживает состояние между вызовами __next__.

Один и тот же класс не должен реализовывать оба метода. Возможно, вам понадобится отдельный класс итераторов, чтобы вы могли иметь несколько независимых итераторов для итерируемой последовательности.

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 - это только один пример класса, реализующего этот протокол; Вы создаете экземпляр generator, используя выражение генератора ((x for x in [1,2,3])) или функцию генератора (т. е. функцию, которая использует yield).

...