Question

Does anyone have a real world example outside of python's file object implementation of an __enter__ and __exit__ use case? Preferably your own, since what I'm trying to achieve is a better way to conceptualize the cases where it would be used.

I've already read this.

And, here's a link to the python documentation.

Was it helpful?

Solution

There are many uses. Just in the standard library we have:

  • sqlite3; using the connection as a context manager translates to committing or aborting the transaction.

  • unittest; using assertRaises as a context manager lets you assert an exception is raised, then test aspects of the exception.

  • decimal; localcontext manages decimal number precision, rounding, and other aspects.

  • threading objects such as locks, semaphores and conditions are context managers too; letting you obtain a lock for a set of statements, etc.

  • the warnings module gives you a context manager to temporarily catch warnings.

  • many libraries offer closing behaviour, just like the default file object. These include the tarfile and the zipfile modules.

  • Python's own test.test_support module uses several context managers, to check for specific warnings, capture stdout, ignore specific exceptions and temporarily set environment variables.

Any time you want to detect when a block of code starts and / or ends, you want to use a context manager. Where before you'd use try: with a finally: suite to guarantee a cleanup, use a context manager instead.

OTHER TIPS

I've found it useful to have a contextmanager version of os.chdir(): on exit it chdir()s back to the original directory.

This allows you to emulate a common (Bourne) shell-scripting pattern:

(
cd <some dir>
<do stuff>
)

I.e. you change to a new dir <some dir> inside a subshell (the ( )) so that you are sure to return to your original dir, even if the <do stuff> causes an error.

Compare the context manager and vanilla versions in Python. Vanilla:

original_dir = os.getcwd()
os.chdir(<some dir>)
try:
    <do stuff>
finally:
    os.chdir(original_dir)

Using a context manager:

with os.chdir(<some dir>):
    <do stuff>

The latter is much nicer!

There are a few examples on the Python Wiki.

The canonical answer is locks:

with (acquire some mutex):
    # do stuff with mutex

Here's a Stack Overflow question and answer involving locks and the with statement.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top