У меня есть следующий код.
def gen():
while True: # line 2
d = yield # line 3
yield d # line 4
x = gen()
next(x)
for i in (3, 4, 5):
print(x.send(i)) # line 10
Когда я запускаю это, я получаю:
3
None
5
скорее, чем:
3
4
5
чего я и ожидал. Я уже прошел через несколько подобных вопросов (включая этот), но я все еще не понимаю, что здесь происходит.
Мое понимание заключается в следующем:
Мы запускаем генератор, вызывая next(x)
, он начинает выполнение и входит в цикл while
в строке 2. В строке 3 у нас есть оператор yield
, и выполнение приостанавливается. В строке 10 мы отправляем значение 3
. Выполнение возобновляется в строке 3, d
устанавливается на 3
, и мы возвращаемся обратно d
. В строке 10 send
возвращает полученное значение (3
). Генератор продолжает выполнение, пока мы не вернемся к оператору yield
в строке 3 и т. д.
Это неправильно? Что я здесь делаю неправильно?
@KellyBundy один для получения значения от send
, другой для возврата значения
Но оба возвращают значение...
@KellyBundy, не могли бы вы уточнить? Я относительно новичок в этом, но я подумал, что d = yield
по существу служит для приема входящих данных (блокировка до тех пор, пока данные не будут доступны), а yield d
служит для создания исходящих данных.
@mlz7 d = yield d
является допустимым синтаксисом. Вы можете сделать оба сразу.
@ Axe319 А, понятно, значит d = yield
всегда будет неявно yield None
?
Это больше, чем «можно делать и то и другое одновременно» — вы всегда делаете и то, и другое одновременно, но, например. yield d
не сохраняет полученное и d = yield
уступает None
при получении значения.
Да. Добавьте что-то вроде d = yield
перед циклом while
. next(x)
будет продвигаться к этому yield
неявно уступая None
. x.send(i)
отправит i
, назначит его d
и перейдет к следующему yield
, возвращая d
обратно. А потом повторить.
x = yield y
делает две вещи:
y
.x
.Без y
возвращается None
. Без x =
отправленное значение просто выбрасывается.
Итак, что здесь происходит:
code effects comments
---------------------------------------------
d = yield return None ok, you ignore it
d = 3
yield d return 3 gets printed
Throw away 4
d = yield return None gets printed
d = 5
yield d return 5 gets printed
Вы можете исправить это так, всегда сохраняя и возвращая каждое отправленное значение:
def gen():
d = None # or `d = yield`, either works, just differently
while True:
d = yield d
Почему вы используете два
yield
s?