Кажется, что выражение yield работает как functools.partial
, [за исключением того], что оно должно быть заполнено с использованием next()
.
Я не уверен, что именно заставляет вас так говорить, но я не сразу вижу параллели. functools.parital
предназначен для точного связывания некоторых args / kwargs с вызываемым и позволяет вам сохранять некоторые другие args / kwargs для вызова пользователем. («partial()
используется для частичного применения функции, которое« замораживает »некоторую часть аргументов и / или ключевых слов функции, что приводит к созданию нового объекта с упрощенной подписью».) Это не совсем то, что происходит с этим генератором или любым другим генератор.
Сложно следовать сопрограмме, насколько я понимаю правильное направление, чтобы продолжить без дальнейших побочных эффектов, так как Python назвал его def
вместо class
?
Они хитры, согласны с вами там. Но я не уверен, вижу ли я, что сопрограмма "похожа на класс по своей природе". Сопрограмма - это специализированный генератор. Генераторы определены с def
и могут приостанавливать и возобновлять их выполнение. Это описывает генераторы, а не классы, и просто замена def
на class
была бы синтаксически недействительной, для начала.
Одним из способов выражения любого выражения, например a = yield b
, является обозначение точки останова.
Когда вы звоните next(g)
, он продвигается, пока не достигнет оператора yield
, и остановится на этом. Он поместит полученное значение в стек вызовов , но приостановит его выполнение и остановится там, будучи возобновляемым, когда вы снова вызовете next()
для него. (Это ключевое различие между функциями и генераторами и между функциями и сопрограммами по расширению.)
При первом вызове next()
, line
равен None
. (В основном, line = yield None
.) Вы не сможете повторить это, потому что не можете сказать for pattern in None
. Что означает «заправка» в этом случае, вероятно, относится к тому факту, что первоначальный вызов next(g)
аналогичен g.send(None)
.
Теперь, когда вы отправляете дополнительные значения в генератор, они будут назначены на line
, тогда как pattern
остается «питоном». Если "питон" найден во всем, что вы .send()
, он печатается.
>>> g = grep("python")
>>> n = g.send(None) # equiv to next(g); stop at line = (yield)
Looking for python
>>> n is None
True
>>> g.send("coroutine test")
>>> g.send("coroutine test")
>>> g.send("coroutine test") # no match
>>> g.send("learning python") # match
learning python
>>> g.send("python3.7") # match
python3.7