Julien Spronck
Julien Spronck

Reputation: 15433

What is the optimal use of a lock with a try ... except in Python 2.7?

Suppose that I have a threading.Lock() object that I want to acquire in order to use a resource. Suppose I want to use a try ... except ... clause with the resource.

There are several ways of doing this.

Method 1

import threading
lock = threading.Lock()
try:
    with lock:
        do_stuff1()
        do_stuff2()
except:
    do_other_stuff()

If an error occurs during do_stuff1() or do_stuff2(), will the lock be released? Or is it better to use one of the following methods?

Method 2

with lock:
    try:
        do_stuff1()
        do_stuff2()
    except:
        do_other_stuff()

Method 3

lock.acquire():
try:
    do_stuff1()
    do_stuff2()
except:
    do_other_stuff()
finally:
    lock.release()

Which method is best for the lock to be released even if an error occurs?

Upvotes: 9

Views: 4247

Answers (1)

jonrsharpe
jonrsharpe

Reputation: 122091

The with "context manager" requires an __exit__ method, which in this case will ensure that, whatever happens, the lock is released.

If you want to handle exceptions that occur during whatever it is that you're doing with that lock, you should put the try inside the with block, i.e. Method 2 is the correct approach. In general, you should always aim to minimise the amount of code within the try block.

You should also be as specific as possible about what could go wrong; a bare except: is bad practice (see e.g. "the evils of except"). At the very least (even for a simple example!) you should use except Exception:.

Upvotes: 9

Related Questions