Default scope of variables

Wayne Werner wayne at waynewerner.com
Sun Jul 7 09:13:43 EDT 2013


On Fri, 5 Jul 2013, Chris Angelico wrote:

> Oh. Uhm... ahh... it would have helped to mention that it also has a
> commit() method! But yes, that's correct; if the object expires (this
> is C++, so it's guaranteed to call the destructor at that close brace
> - none of the Python vagueness about when __del__ is called) without
> commit() being called, then the transaction will be rolled back.

If one wants to duplicate this kind of behavior in Python, that's what 
context managers are for combined with a `with` block, which does 
guarantee that the __exit__ method will be called - in this case it could 
be something as simple as:

from contextlib import contextmanager

@contextmanager
def new_transaction(conn):
     tran = conn.begin_transaction()
     yield tran
     if not tran.committed:
         tran.rollback()



Which you would then use like:


conn = create_conn()
with new_transaction(conn) as tran:
      rows_affected = do_query_stuff(tran)
      if rows_affected == 42:
           tran.commit()



And then you get the desired constructor/destructor behavior of having 
guaranteed that code will be executed at the start and at the end. You can 
wrap things in try/catch for some error handling, or write your own 
context manager class.

HTH,
Wayne



More information about the Python-list mailing list