coroutine, throw, yield, call-stack and exception handling
Veek. M
vek.m1234 at gmail.com
Tue Feb 9 06:55:56 EST 2016
Ian Kelly wrote:
> On Mon, Feb 8, 2016 at 2:17 AM, Veek. M <vek.m1234 at gmail.com> wrote:
>> ****************************
>> Exceptions can be raised inside a coroutine using the throw(
>>
>> Exceptions raised in this manner will originate at the currently
>> executing yield state-ment in the coroutine.A coroutine can elect to
>> catch exceptions and handle them as appropriate. It is not safe to
>> use throw() as an asynchronous signal to a coroutine—it should never
>> be invoked from a separate execution thread or in a signal handler.
>> ****************************
>>
>> What does Beazley mean by this: 'will originate at the currently
>> executing yield state-ment in the coroutine'
>>
>> If he's throw'ing an exception surely it originates at the throw:
>>
>> def mycoroutine():
>> while len(n) > 2:
>> n = (yield)
>>
>> throw('RuntimeError' "die!")
>
> The "throw" is not called from inside the coroutine. It's a method of
> the generator object, and it's used by the calling code. It's similar
> to calling the send method, except that instead of passing a value to
> be returned by the yield expression, it passes an exception to be
> raised inside the coroutine at the yield expression.
>
> Example:
>
> def mycoroutine():
> n = 0
> while True:
> try:
> n = (yield n)
> except SomeException:
> n = 42
>
> coro = mycoroutine()
> coro.next()
> for i in range(100):
> if i % 6 == 0:
> coro.send(i % 6)
> else:
> coro.throw(SomeException())
>
>
>> Also this bit:
>> ***********************
>> If a coroutine returns values, some care is required if exceptions
>> raised with throw() are being handled. If you raise an exception in a
>> coroutine using throw(), the value passed to the next yield in the
>> coroutine will be returned as the result of throw(). If
>> you need this value and forget to save it, it will be lost.
>> ***********************
>>
>> def coroutine():
>> while True:
>> line = (yield result)
>>
>> throw(FooException)
>>
>> where is the question of a 'yield'? You'll exit the coroutine
>> straight away..
>
> Taking my example from above, after SomeException is caught, the next
> value yielded inside the coroutine will be the return value of the
> coro.throw() call. This may be surprising if you're only expecting
> coro.send() and not coro.throw() to return yielded values.
Thanks, that made it abundantly clear :)
More information about the Python-list
mailing list