forked from Volodichev/patterns
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathiterator.py
More file actions
88 lines (69 loc) · 3.61 KB
/
iterator.py
File metadata and controls
88 lines (69 loc) · 3.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
from __future__ import annotations
from collections.abc import Iterable, Iterator
from typing import Any, List
"""
Для создания итератора в Python есть два абстрактных класса из встроенного
модуля collections - Iterable, Iterator. Нужно реализовать метод __iter__() в
итерируемом объекте (списке), а метод __next__() в итераторе.
"""
class AlphabeticalOrderIterator(Iterator):
"""
Конкретные Итераторы реализуют различные алгоритмы обхода. Эти классы
постоянно хранят текущее положение обхода.
"""
"""
Атрибут _position хранит текущее положение обхода. У итератора может быть
множество других полей для хранения состояния итерации, особенно когда он
должен работать с определённым типом коллекции.
"""
_position: int = None
"""
Этот атрибут указывает направление обхода.
"""
_reverse: bool = False
def __init__(self, collection: WordsCollection, reverse: bool = False) -> None:
self._collection = collection
self._reverse = reverse
self._position = -1 if reverse else 0
def __next__(self):
"""
Метод __next __() должен вернуть следующий элемент в последовательности.
При достижении конца коллекции и в последующих вызовах должно вызываться
исключение StopIteration.
"""
try:
value = self._collection[self._position]
self._position += -1 if self._reverse else 1
except IndexError:
raise StopIteration()
return value
class WordsCollection(Iterable):
"""
Конкретные Коллекции предоставляют один или несколько методов для получения
новых экземпляров итератора, совместимых с классом коллекции.
"""
def __init__(self, collection: List[Any] = []) -> None:
self._collection = collection
def __iter__(self) -> AlphabeticalOrderIterator:
"""
Метод __iter__() возвращает объект итератора, по умолчанию мы возвращаем
итератор с сортировкой по возрастанию.
"""
return AlphabeticalOrderIterator(self._collection)
def get_reverse_iterator(self) -> AlphabeticalOrderIterator:
return AlphabeticalOrderIterator(self._collection, True)
def add_item(self, item: Any):
self._collection.append(item)
if __name__ == "__main__":
# Клиентский код может знать или не знать о Конкретном Итераторе или классах
# Коллекций, в зависимости от уровня косвенности, который вы хотите
# сохранить в своей программе.
collection = WordsCollection()
collection.add_item("First")
collection.add_item("Second")
collection.add_item("Third")
print("Straight traversal:")
print("\n".join(collection))
print("")
print("Reverse traversal:")
print("\n".join(collection.get_reverse_iterator()), end="")