> > However, ignored() is actually implemented as a generator function > with the @contextmanager decorator shortcut. This decorator takes a > generator function and wraps it up as a class with the necessary > __enter__ and __exit__ methods. The __enter__ method in this case > calls the .next() method of the generator and returns after it yields > once.
I looked up the source to the decorator found here:http://hg.python.org/cpython/file/406b47c64480/Lib/contextlib.py for anyone interested. It appears that they are using yield so that they can call it again and force it to throw the stop iteration exception. > The __exit__ method calls it again -- or it calls the .throw() > method if an exception was passed in -- and expects the generator to > exit as a result. > > And here to go with what I said above, they want to be able to use the generators throw ability to capture any exception and throw it to the generator, but then why do they *need* the generator to not iterate again? Or in other words, why when they create the context manager via _GeneratorContextManager on line 33, is there the clause in __exit__ to have stop iteration happen or else throw a runtime error? I am thinking this is because it needs the yield to be over so that it can return the control flow to normal, and that subroutine will be done. But I am new to the whole subroutine paradigm so I could be misunderstanding this. Also, if the value was none, why are they instantiating a new exception with value = type()? How could there be a type for the exception without the exception? (From what I understand type is the error type, and value is the error object). So from the perspective of the generator it does its context setup (in > this case, setting up a try block) prior to the yield, and then does > the cleanup (in this case, selectively catching and suppressing the > exceptions) after the yield. > This part makes sense logically. And I like the simplicity. Now I just need to make sure I understand how the yield semantics are allowing this construct to work. Thanks for the reply Ian! > -- > http://mail.python.org/mailman/listinfo/python-list >
-- http://mail.python.org/mailman/listinfo/python-list