when calledthe close(method will raise generatorexit exception at the point the coroutine was waiting for value to be sent in it is normally good policy for coroutines to wrap their yield statements in try finally block so that any cleanup tasks (such as closing associated files or socketscan be performed if we need to raise an exception inside coroutinewe can use the throw(method in similar way it accepts an exception type with optional value and traceback arguments the latter is useful when we encounter an exception in one coroutine and want to cause an exception to occur in an adjacent coroutine while maintaining the traceback both of these features are vital if you're building robust coroutine-based librariesbut we are unlikely to encounter them in our day-to-day coding lives the relationship between coroutinesgeneratorsand functions we've seen coroutines in actionso now let' go back to that discussion of how they are related to generators in pythonas is so often the casethe distinction is quite blurry in factall coroutines are generator objectsand authors often use the two terms interchangeably sometimesthey describe coroutines as subset of generators (only generators that return values from yield are considered coroutinesthis is technically true in pythonas we've seen in the previous sections howeverin the greater sphere of theoretical computer sciencecoroutines are considered the more general principlesand generators are specific type of coroutine furthernormal functions are yet another distinct subset of coroutines coroutine is routine that can have data passed in at one or more points and get it out at one or more points in pythonthe point where data is passed in and out is the yield statement functionor subroutineis the simplest type of coroutine you can pass data in at one pointand get data out at one other point when the function returns while function can have multiple return statementsonly one of them can be called for any given invocation of the function finallya generator is type of coroutine that can have data passed in at one pointbut can pass data out at multiple points in pythonthe data would be passed out at yield statementbut you can' pass data back in if you called sendthe data would be silently discarded