Я не писал ботов для телеграмма раньше. Предположил, что есть что-то вроде куков или подобное.
По вашему выходит, что единственное предназначение генератора - это экономить память. Поверьте, это совсем не так ;)
Любой код, который экономит память генератором, можно написать без него. Больше того - именно этот код и будет лежать в основе нашего генератора.
Но память при этом будет экономить не он, а старый добрый while.
Генератор всего лишь использует тот код, который на самом деле экономит память, обрачивая его в красивый фантик.
Основная идея заключается в том, что компилятор/интерпретатор/что угодно делает некоторую хитрость, чтобы вызывающий мог продолжать вызывать next(), и он будет продолжать возвращать значения - как если бы метод генератора был приостановлен. Теперь очевидно, что вы не можете действительно "приостановить" метод, поэтому компилятор создает для вас машину состояний, чтобы вы помнили, где вы находитесь в данный момент и как выглядят локальные переменные и т.д. Это намного проще, чем писать итератор самостоятельно.
что внутри итератора тоже цикл. Это все обертки над циклом
class Count:
"""Iterator that counts upward forever."""
def __init__(self, start=0):
self.num = start
def __iter__(self):
return self
def __next__(self):
num = self.num
self.num += 1
return num
# вызываем в шелле
>>> c = Count()
>>> next(c)
0
>>> next(c)
1
унутре у него цикл.
Генератор — это объект, который сразу при создании не вычисляет значения всех своих элементов.
Он хранит в памяти только последний вычисленный элемент, правило перехода к следующему и условие, при котором выполнение прерывается.
Вычисление следующего значения происходит лишь при выполнении метода next(). Предыдущее значение при этом теряется.
Этим генераторы отличаются от списков — те хранят в памяти все свои элементы, и удалить их можно только программно. Вычисления с помощью генераторов называются ленивыми, они экономят память
А генератор - всего лишь красивая обертка для этого цикла,
Вот и получается, что это не генератор экономит нам память.
>>> rng = range(10**100)
>>> it = iter(rng)
>>> next(it)
0
>>> next(it)
1
>>> next(it)
2
>>>
>>> it = open("test.txt")
>>> next(it)
'1\n'
>>> next(it)
'\x02\n'
>>> next(it)
'3\n'
>>> next(it)
'4'
>>> next(it)
Traceback (most recent call last):
File "<pyshell#30>", line 1, in <module>
next(it)
StopIteration
>>>
>>> # или все тоже самое через цикл:
>>> for line in open("test.txt"): print(line)
goto flag - это самый базовый вариант цикла и есть
Но ваш пример не экономит память, а речь была именно об экономии.
что генератор её не экономит.
<?php
function gen() {
yield 1;
yield 2;
yield 3;
yield 4;
}
$g = gen();
$i = 1;
flag:
echo $g->current(), "\n";
$g->next();
$i++;
if($i <= 4) goto flag;
?>
Значения генерирует не генератор, а цикл.
генератор не будет экономить память без цикла
Почему генераторы потребляют меньше памяти, чем массивы?
никакой полезной функциональности не несут. Это просто обертка для красоты
А генератор всего лишь позволяет замаскировать этот цикл, как будто понарошку мы работаем не с циклом, а с массивом.
Посмотри как реализовано middleware recover в любом фреймворке тип gin, echo, fiber.
Изначальный вариант в fiber: https://github.com/gofiber/recover/blob/master/main.go
Сейчас оно уже встроено: https://github.com/gofiber/fiber/blob/master/middl...
Один раз написал, потом оно юзается в каждом запросе: