A "scopeguard" for Python

Robert Kern robert.kern at gmail.com
Thu Mar 4 20:04:30 EST 2010


On 2010-03-04 15:19 PM, Mike Kent wrote:
> On Mar 3, 12:00 pm, Robert Kern<robert.k... at gmail.com>  wrote:
>> On 2010-03-03 09:39 AM, Mike Kent wrote:
>>
>>> What's the compelling use case for this vs. a simple try/finally?
>>
>>>      original_dir = os.getcwd()
>>>      try:
>>>          os.chdir(somewhere)
>>>          # Do other stuff
>>>      finally:
>>>          os.chdir(original_dir)
>>>          # Do other cleanup
>>
>> A custom-written context manager looks nicer and can be more readable.
>>
>> from contextlib import contextmanager
>> import os
>>
>> @contextmanager
>> def pushd(path):
>>       original_dir = os.getcwd()
>>       os.chdir(path)
>>       try:
>>           yield
>>       finally:
>>           os.chdir(original_dir)
>>
>> with pushd(somewhere):
>>       ...
>
> Robert, I like the way you think.  That's a perfect name for that
> context manager!  However, you can clear one thing up for me... isn't
> the inner try/finally superfluous?  My understanding was that there
> was an implicit try/finally already done which will insure that
> everything after the yield statement was always executed.

No, the try: finally: is not implicit. See the source for 
contextlib.GeneratorContextManager. When __exit__() gets an exception from the 
with: block, it will push it into the generator using its .throw() method. This 
raises the exception inside the generator at the yield statement.

-- 
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
  that is made terrible by our own mad attempt to interpret it as though it had
  an underlying truth."
   -- Umberto Eco




More information about the Python-list mailing list