Python language basics 85: file I/O resource management with try-finally

Introduction

In the previous post we started looking into file operations in Python. We discussed various basic terms such as the file access mode and character encoding. We also went through some very basic code to write to a text file. We saw that the code wasn’t well designed. It is error-prone and not very reliable.

In this post we’ll present a way to make the code better with a traditional try-except-finally block.

Try-finally

We looked at exception handling before in this series so I’ll not go through it again. We can enclose the file handling code in a try-finally block to make sure that open resources are closed regardless of the actual code execution.

In its simplest form we can have the following:

try:
    fullpath = os.path.join('C:/', 'tmp', 'source.txt')
    file = open(fullpath, mode='wt', encoding='UTF-8')
    file.write('This is some content, ')
    file.write('this is some more content, ')
    file.write('good bye for now.')
finally:
    print("Closing the file...")
    file.close()

Note how we put the filehandle.close function in the finally block. That’s a very basic form of resource management to prevent memory leaks. This prints Closing the file… in the output window regardless of the outcome of the try block. If I provide a non-existent folder path, such as c:\nosuchfolder then I get the following result:

Closing the file…
FileNotFoundError: [Errno 2] No such file or directory: ‘C:/nosuchfolder\\source.txt’

However, there’s one more error:
UnboundLocalError: local variable ‘file’ referenced before assignment

The reason is that the open method threw an exception BEFORE the ‘file’ variable could have been initialised. The moment we reach the file.close part the variable file is null, therefore we cannot call the close method on it. In that case we’re actually safe as the file handle wasn’t open in the first place.

We can of course catch that error and handle it gracefully. We can also add exception handling in case an error is thrown in the try block. The most common exception type we can encounter during file operations is the IOError:

try:
    fullpath = os.path.join('C:/', 'nosuchfolder', 'source.txt')
    file = open(fullpath, mode='wt', encoding='UTF-8')
    file.write('This is some content, ')
    file.write('this is some more content, ')
    file.write('good bye for now.')
except IOError as e:
    print('Error: {0}'.format(e))
finally:
    print("Closing the file...")
    try:
        file.close()
    except UnboundLocalError as ule:
        print('Could not close file: {0}'.format(ule))

The above code produces the following output:

Error: [Errno 2] No such file or directory: ‘C:/nosuchfolder\\source.txt’
Closing the file…
Could not close file: local variable ‘file’ referenced before assignment

The above code is better than what it looked like previously. It handles errors and takes care of cleaning up the resources after it. However, we can improve it further with a ‘with’ block which takes care of closing the resources for us. We’ll see how it works in the next part.

Read all Python-related posts on this blog here.

Advertisements

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

ultimatemindsettoday

A great WordPress.com site

iReadable { }

.NET Tips & Tricks

Robin Sedlaczek's Blog

Developer on Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

the software architecture

thoughts, ideas, diagrams,enterprise code, design pattern , solution designs

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Cyber Matters

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: