def coroutine(func)def start(*args,**kwargs) func(*args,**kwargsg next(return return start using this decoratoryou would write and use coroutines using@coroutine def receiver()print("ready to receive"while truen (yieldprint("got %snexample use receiver( send("hello world"note no initial next(needed coroutine will typically run indefinitely unless it is explicitly shut down or it exits on its own to close the stream of input valuesuse the close(method like thisr close( send( traceback (most recent call last)file ""line in stopiteration once closeda stopiteration exception will be raised if further values are sent to coroutine the close(operation raises generatorexit inside the coroutine as described in the previous section on generators for exampledef receiver()print("ready to receive"trywhile truen (yieldprint("got %snexcept generatorexitprint("receiver done"exceptions can be raised inside coroutine using the throw(exctype [value [tb]]method where exctype is an exception typevalue is the exception valueand tb is traceback object for exampler throw(runtimeerror,"you're hosed!"traceback (most recent call last)file ""line in file ""line in receiver runtimeerroryou're hosedexceptions raised in this manner will originate at the currently executing yield statement in the coroutine coroutine can elect to catch exceptions and handle them as appropriate it is not safe to use throw(as an asynchronous signal to coroutine--it should never be invoked from separate execution thread or in signal handler coroutine may simultaneously receive and emit return values using yield if values are supplied in the yield expression here is an example that illustrates thisdef line_splitter(delimiter=none)print("ready to split"result none while trueline (yield resultresult line split(delimiterf lib fl ff