program structure and control flow the with obj statement accepts an optional as var specifier if giventhe value returned by obj _enter_ (is placed into var it is important to emphasize that obj is not necessarily the value assigned to var the with statement only works with objects that support the context management protocol (the _enter_ (and _exit_ (methodsuser-defined classes can implement these methods to define their own customized context-management here is simple exampleclass listtransaction(object)def _init_ (self,thelist)self thelist thelist def _enter_ (self)self workingcopy list(self thelistreturn self workingcopy def _exit_ (self,type,value,tb)if type is noneself thelist[:self workingcopy return false this class allows one to make sequence of modifications to an existing list howeverthe modifications only take effect if no exceptions occur otherwisethe original list is left unmodified for exampleitems [ , , with listtransaction(itemsas workingworking append( working append( print(itemsproduces [ , , , , trywith listtransaction(itemsas workingworking append( working append( raise runtimeerror("we're hosed!"except runtimeerrorpass print(itemsproduces [ , , , , the contextlib module allows custom context managers to be more easily implemented by placing wrapper around generator function here is an examplefrom contextlib import contextmanager @contextmanager def listtransaction(thelist)workingcopy list(thelistyield workingcopy modify the original list only if no errors thelist[:workingcopy in this examplethe value passed to yield is used as the return value from _enter_ (when the _exit_ (method gets invokedexecution resumes after the yield if an exception gets raised in the contextit shows up as an exception in the generator function if desiredan exception could be caughtbut in this caseexceptions will simply propagate out of the generator to be handled elsewhere lib fl ff