Run Code after Your Program Exits with Python’s AtExit

Register cleanup functions that run after your script ends or errors

Run Code after Your Program Exits with Python’s AtExit
(image by Andrew Teoh on Unsplash)

In this article I’ll show you how to register functions that execute when your program exits with python’s built-in module atexit. This means that you can run code after your code exits (due to an error of when it’s finished), providing you with all kinds of essential tools to execute clean-up functions, save your data, and make debugging easier. Let’s code!


1. Understanding atexit with simple examples

The main concept is to register a function that gets executed when the script exits. This can happen for many reasons which we’ll get into later. Let’s start with the simplest example and gradually make it more useful.


Simplest example — registering a function

The code below demonstrates most basic way of registering a exit-function.

In the code above we simply register the say_goodbye function and then call the simple_example function. When the script ends after simple_example() has completed you’ll see that say_goodbye executes. This is also visible in the output:calling the function..
Function enter
Function exit
exiting now, goodbye

Easy! Let’s make it a little more complex.

Why Python is so slow and how to speed it up
Take a look under the hood to see where Python’s bottlenecks lie

Simple example — exiting a loop

We adjust the simple_example function a little: it now contains an infinite loop that prints “still running..” every second. Again we register the say_goodbye function, only now at the start of the simple_example function.

Now when we run the code we’ll see a “still running..” message each second. When we exit by pressing ctrl-c we see the following output:still running..
still running..
still running..
still running..
still running..
exiting now, goodbye

So before we entered the infinite loop, we registered the say_goodbye function. This function will execute when the interpreter terminates.

Applying Python multiprocessing in 2 lines of code
When and how to use multiple cores to execute many times faster!

2. Simpler and multiple registrations

In the previous part we’ve seen that its pretty important where you place the atexit.register bit of code. If we register the function after the while loop the function will never get registered.

In this part we explore a new way of registering the functions so that you don’t have to worry about this problem. Also we discover that you can register multiple multiple functions

we can exit all we want It is possible to have multiple functions registered atexit. Also, registration can be a bit simpler.


Simpler registration with a decorator

By registering functions with a decorator you don’t have to worry about when you register the function since they happen as soon as the interpreter reaches your function definition. They are also super easy to use:

Another advantage is that your code is much cleaner; the simpel_example() function is not ‘polluted’ with the atexit registration. Check out this article if you want to learn more about how decorator work and how to create your own.

How to Make a Database Connection in Python for Absolute Beginners
3 steps (+examples) to connect to MS SQL Server, MySQL, Oracle and many other databases

Registering multiple functions

It is easy to register multiple functions to execute at exit. The important thing is to remember they are executed in the reversed order in which they were registered. Check out the code below:

You can see the order by the outputs below:still running..
still running..
# 1 says au revoir
# 2 says later
# 3 says goodbye

Understanding Python Context-Managers for Absolute Beginners
Understand the WITH statement with lightsabers

Unregistering a function

This is as easy as registering a function:

The code above will produce the following output (notice that “# 2” doesn’t show):Function enter
Function exit
# 1

You can also clear all registered functions using atexit._clear().

Cython for absolute beginners: 30x faster code in two simple steps
Easy Python code compilation for blazingly fast applications

Registering a function with arguments

The code below allows you to pass arguments to the registered exit-function. This can be pretty useful for passing data to your registration function that you don’t know beforehand:

The code above produces the following output:what is your name? mike
Function enter
Function exit
-mike says hoi after 0:00:01.755111
-mike says hello after 0:00:01.755111
-mike says bonjour after 0:00:01.755111
-mike says gutentag after 0:00:01.755111

Docker for absolute beginners: the difference between an image and a container
Learn the difference between Docker images and containerscontainers and images are different + practical code examples

Manually trigger all registered exit functions

The code below demonstrates how to manually trigger all registered exit-functions with the atexit._run_exitfuncs() function:

The output looks like this:start
exiting now, au revoir
exiting now, later
exiting now, goodbye
continue with code

Detecting motion with OpenCV — image analysis for beginners
How to detect and analyze moving objects with OpenCV

When does atexit run the registered functions?

Good question. Exit function get executed upon normal interpreter termination. This means that they run when your script ends normally, when sys.exit(0) quit() or raising an exception like raise ValueError("oops").

Abnormal termination is a situation in which the program is killed by a signal that is not handled by Python or when a Python fatal internal error is detected. The last case is when os._exit(0) is called; this exits without calling cleanup handlers, flushing stdio buffers, etc. As an example:

will produce:start
exiting now, goodbye

Wheereas replacing sys.exit(0) by os._exit(0) will not run the say_goodbye function.

Create a fast auto-documented, maintainable and easy-to-use Python API in 5 lines of code with…
Perfect for (unexperienced) developers who just need a complete, working, fast and secure API

Conclusion

In this article we’ve explored the inner workings of Python’s atexit function, and how and when to use it.

I hope this article was as clear as I hope it to be but if this is not the case please let me know what I can do to clarify further. In the meantime, check out my other articles on all kinds of programming-related topics like these:

Happy coding!

— Mike

P.S: like what I’m doing? Follow me!

Join Medium with my referral link — Mike Huls
Read every story from Mike Huls (and thousands of other writers on Medium). Your membership fee directly supports Mike…