Clean-up actions

Sometimes you need to perform a clean-up action irrespective of whether an operation succeeds. In a later module we'll introduce context managers which are the modern solution to this common situation, but here we'll introduce the tryfinally construct, since creating a context manager can be overkill in simple cases. In any case, an understanding of tryfinally is useful for making your own context managers.

Consider this function, which uses various facilities of the standard library os module to change the current working directory, create a new directory at that location, and then restore the original working directory:

import os

def make_at(path, dir_name):
original_path = os.getcwd()
os.chdir(path)
os.mkdir(dir_name)
os.chdir(original_path)

At first sight this seems reasonable, but should the call to os.mkdir() fail for some reason the current working directory of the Python process won't be restored to it's original value, and the make_at() function will have had an unintended side-effect.

To fix this, we'd like the function to restore the original current working directory under all circumstances. We can achieve this with a tryfinally block. Code in the finally block is executed whether execution leaves the try block normally by reaching the end of the block, or exceptionally by an exception being raised.

This construct can be combined with except blocks, used below to add a simple failure logging facility:

import os
import sys

def make_at(path, dir_name):
original_path = os.getcwd()
try:
os.chdir(path)
os.mkdir(dir_name)
except OSError as e:
print(e, file=sys.stderr)
raise
finally:
os.chdir(original_path)

Now, if os.mkdir() raises an OSError, the OSError handler will be run and the exception will be re-raised. But since the finally block is always run no matter how the try-block ends, we can be sure that the final directory change will take place in all circumstances.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset