Pull to refresh

Comments 8

Небольшой трюк для любителей итераторов.

class MyRange:
    def __init__(self, start, end):
        self.start = start
        self.end = end

    def __iter__(self):
        return iter(range(self.start, self.end))

UFO landed and left these words here

Неплохая статья, но обнаружил неточность в описании пункта 4(__getitem__ ).
Все-таки к элементам по индексу в словаре мы не можем обращаться, только по ключу.

numbers = MyRange(1, 5)
iterator = iter(numbers)  # Получаем итератор
print(next(iterator))  # Выведет: 1
print(next(iterator))  # Выведет: 2
print(next(iterator))  # Выведет: 3
print(next(iterator))  # Выведет: 4
print(next(iterator))  # Выведет: StopIteration исключение

iterator = iter(numbers)  # Пытаемся получить новый итератор
print(next(iterator))  # Надеемся, что он выдаст 1, но получаем StopIteration исключение
# WTF?! Нам подсунули использованный итератор!!

ну да, мы возвращаем self, который не меняется если ещё раз выполнить iter(numbers), а внутри iter метода мы счётчик start никак не обнуляем, поэтому вызывается исключение. Если бы автор выделил для переменной счётчика отдельную переменную и обнулил её, тогда при попытке второй раз воспользоваться итератором всё было бы хорошо.

Не стоит называть эти методы магическими. В них нет никакой магии, когда мы получаем результат, но не знаем, что происходит внутри в процессе его получения. Эти методы стоит называть специальными или предзаданными (predefined), т.к. они предназначены для решения конкретных задач понятным описанным в документации способом и не могут быть переопределены.

Магические - тому що простые. На джаве, например, просто так не переопределишь поведение. А тут парой строк можно обойтись

Sign up to leave a comment.

Articles