'Python coroutine can one `send` without first doing `next`?
When sending a value to a generator/coroutine, is there a way to avoid that initial next(g)?
def gen(n):
m = (yield) or "did not send m to gen"
print(n, m)
g = gen(10)
next(g)
g.send("sent m to g") # prints "10 sent m to g"
Without next(g), we get
TypeError: can't send non-None value to a just-started generator
Solution 1:[1]
The error stems from this bit of code in CPython's gen_send_ex2, i.e. it occurs if gi_frame_state is FRAME_CREATED.
The only place that matters for this discussion that sets gi_frame_state is here in gen_send_ex2, after a (possibly None) value has been sent and a frame is about to be evaluated.
Based on that, I'd say no, there's no way to send a non-None value to a just-started generator.
Solution 2:[2]
Not sure if this is helpful in your specific case, but you could use a decorator to initialize coroutines.
def initialized(coro_func):
def coro_init(*args, **kwargs):
g = coro_func(*args, **kwargs)
next(g)
return g
return coro_init
@initialized
def gen(n):
m = (yield) or "did not send m to gen"
print(n, m)
g = gen(10)
g.send("sent m to g") # prints "10 sent m to g"
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | AKX |
| Solution 2 | timgeb |
