Как итератор, эквивалентный itertools.count, будет реализован в Python без использования функции генератора? - PullRequest
0 голосов
/ 02 февраля 2019

С помощью функции генератора, вот как можно реализовать itertools.count (из документации ):

def count(start=0, step=1):
    # count(10) --> 10 11 12 13 14 ...
    # count(2.5, 0.5) -> 2.5 3.0 3.5 ...
    n = start
    while True:
        yield n
        n += step

Я пытаюсь найти, как подобный итератор мог бы быть реализован безфункция генератора.

class Count:
    def __init__(self, start=0, step=1):
        self.c = start
        self.step = step

    def __iter__(self):
        return self

    def __next__(self):
        n = self.c
        self.c += self.step
        return n

Это реализация?

Конечно, это не имеет никакого практического смысла, смысл просто в том, чтобы получить представление о том, как это достигается с помощью генераторов..

Ответы [ 2 ]

0 голосов
/ 03 июля 2019

Вы можете использовать collections.abc.Iterator, чтобы реализовать счетчик с меньшим количеством кода

from collections.abc import Iterator

class count(Iterator):
    def __init__(self, start=0, step=1):
        self.c, self.step = start-step, step

    def __next__(self):
        self.c += self.step
        return self.c
0 голосов
/ 02 февраля 2019

Одной из лучших практик является написание небольшого модульного теста.Для этого вы можете использовать unittest framework.

Вот пример с несколькими тестами, которые используют ваш класс в цикле и проверяют значения вашего итератора:

import unittest
import random


class TestCount(unittest.TestCase):
    loops = 20

    def test_default(self):
        c = Count()
        for i in range(self.loops):
            self.assertEqual(i, next(c))

    def test_start(self):
        start = random.randint(-10, 10)
        c = Count(start=start)
        for i in range(start, start + self.loops):
            self.assertEqual(i, next(c))

    def test_step_pos(self):
        step = random.randint(1, 5)
        c = Count(step=step)
        for i in range(0, self.loops, step):
            self.assertEqual(i, next(c))

    def test_step_neg(self):
        step = random.randint(-5, -1)
        c = Count(step=step)
        for i in range(0, -self.loops, step):
            self.assertEqual(i, next(c))
...