A "scopeguard" for Python

Alf P. Steinbach alfps at start.no
Wed Mar 3 16:10:26 CET 2010

For C++ Petru Marginean once invented the "scope guard" technique (elaborated on 
by Andrei Alexandrescu, they published an article about it in DDJ) where all you 
need to do to ensure some desired cleanup at the end of a scope, even when the 
scope is exited via an exception, is to declare a ScopeGuard w/desired action.

The C++ ScopeGuard was/is for those situations where you don't have proper 
classes with automatic cleanup, which happily is seldom the case in good C++ 
code, but languages like Java and Python don't support automatic cleanup and so 
the use case for something like ScopeGuard is ever present.

For use with a 'with' statement and possibly suitable 'lambda' arguments:

class Cleanup:
     def __init__( self ):
         self._actions = []

     def call( self, action ):
         assert( is_callable( action ) )
         self._actions.append( action )

     def __enter__( self ):
         return self

     def __exit__( self, x_type, x_value, x_traceback ):
         while( len( self._actions ) != 0 ):
             except BaseException as x:
                 raise AssertionError( "Cleanup: exception during cleanup" ) from

I guess the typical usage would be what I used it for, a case where the cleanup 
action (namely, changing back to an original directory) apparently didn't fit 
the standard library's support for 'with', like

   with Cleanup as at_cleanup:
       # blah blah
       chdir( somewhere )
       at_cleanup.call( lambda: chdir( original_dir ) )
       # blah blah

Another use case might be where one otherwise would get into very deep nesting 
of 'with' statements with every nested 'with' at the end, like a degenerate tree 
that for all purposes is a list. Then the above, or some variant, can help to 
/flatten/ the structure. To get rid of that silly & annoying nesting. :-)


- Alf (just sharing, it's not seriously tested code)

More information about the Python-list mailing list