#python #yield
Пример из изучаемой мною книжки def fibonacci_generator(): a = b = 1 while True: yield a a, b = b, a + b print(a, b) #поможет лучше понять работу fib = fibonacci_generator() for i in fib: if i > 100: break else: print('Generated:', i) Что в данном коде выполняет функция yield? В книге написано - "Она [генераторная инструкция], начинается с ключевого слова yield и определяет объект-генератор (то есть переменную a?), который возвращается оператору (print?), вызвавшему функцию. Когда генераторная инструкция исполняется, состояние объекта генератора "замораживается" и сохраняется. Объект, возвращаемый генераторной инструкцией, может быть присвоен переменной (это мы сделали на 7 строке кода?)." Но я так и не понял, как это отражается в результате кода? Я пытаюсь понять работу кода сопоставив код с результатом его выполнения. Вот несколько строк результата: Generated: 1 1 2 Generated: 1 2 3 Generated: 2 3 5 Generated: 3 5 8 Generated: 5 8 13 ... Что после операций a, b = b, a + b становится содержимым функции fibonacci_generator? Результат суммы a и b? Переменная а на второй итерации равна 2, потому что "при этом она сохраняет состояние своего последнего вызова и при следующем вызове продолжает работу с той же точки."? Почему, к примеру, на первой итерации, вывод переменной b отображает 2, ведь сумма а + b просто какое-то, ничему не присвоенное выражение?
Ответы
Ответ 1
yield определяет объект-генератор (то есть переменную a?) Нет, под объектом генератором подразумевается вся функция целиком. Она преобразуется в генератор, если в её теле присутствует инструкция yield. Переменная a — это то, что будет генерироваться и возвращаться. который возвращается оператору (print?) Нет, генератор в Вашем коде возвращается и присваивается переменной fib: fib = fibonacci_generator() print(type(fib)) #Объект, возвращаемый генераторной инструкцией, может быть присвоен переменной (это мы сделали на 7 строке кода?) Нет, в 7 строке кода Вы возвращаете новое сгенерированное значение и замораживаете генератор, а присваивание этого значения переменной неявно происходит в 9 строке кода: for i in fib: ... Инструкция for на каждой итерации будет присваивать i какое-то значение. Для этого она будет обращаться к функции (через методы итерирования). Вы вручную можете получать новые значения из генератора, используя функцию next: i = next(fib) Попробуйте отказаться от цикла for и использовать только инструкцию выше, чтобы лучше понять, как генератор возвращает новое значение. a, b = b, a + b Это сокращённая запись кортежного присваивания: (a, b) = (b, a + b) Элементы из левого кортежа будут сопоставлены с элементами из правого (количество должно быть одинаково) и им будут присвоены соответствующие значения. Ответ 2
a, b = c, d это почти то же самое, что a = c b = d только вычисляется не последовательно, а справа налево. Чтобы поменять местами два значения можно написать a, b = b, a У тебя почти то же самое, но вместо второй переменной сумма: a, b = b, a + bОтвет 3
Генераторы это очень интересная штука. https://docs.python.org/3/reference/expressions.html#generator-expressions Вот документация. Простым языком: yield - это выражение, которое используется при создании функции-генераторы или асинхронного генератора. Еще проще: генератор - это конструкция, в которой реализован протокол итератора, т.е. любой генератор = итерируемая последовательность, которую можно перебирать в цикле, как списки, только значения она возвращает вызовом метода next(), значит - не сразу, а последовательно, за каждое обращение.
Комментариев нет:
Отправить комментарий