3

Below is the code written in a script say test_atexit.py

def exit_function():
    print "I am in exit function"
import atexit
atexit.register(exit_function)
print "I am in main function"

When i run the function using python2.4 then exit_function is being called

$python2.4 test_atexit.py  
I am in main function  
I am in exit function

When i run the same using ipython then exit_function is not being called

$ ipython  
In [1]: %run test_atexit.py  
I am in main function  
In [2]: 

why exit_function is not called when running script using Ipython and how can i make ipython to call exit_function

viky
  • 91
  • 7

1 Answers1

4

atexit functions are called when the Python interpreter exits, not when your script finishes. When you %run something in IPython, the interpreter is still running until you quit IPython. When you do that, you should see the output from your exit_function().

Possibly what you want is a try/finally, which ensures that the finally code is run after the try block, even if an exception occurs:

try:
    print("Doing things...")
    raise Exception("Something went wrong!")
finally:
    print("But this will still happen.")

If you really need to make atexit functions run, then you can call atexit._run_exitfuncs. However, this is undocumented, and it may do unexpected things, because anything can register atexit functions - IPython itself registers half a dozen, so you're likely to break things if you do it in IPython.

(Also, Python 2.4? For the sanity of developers everywhere, if it's possible to upgrade, do so ;-) )

Thomas K
  • 39,200
  • 7
  • 84
  • 86
  • Thanks for the reply Thomas. My requirement is to invoke an exit function at the end of script in ipython, not at the exit of Ipython interpreter. Is there any away to invoke the same? – viky Apr 03 '14 at 08:43
  • A try/finally is probably what you're after. – Thomas K Apr 03 '14 at 23:35
  • Do you know of a way to wrap your entire interactive IPython session in a try/finally? – Ellis Percival Jan 22 '16 at 09:01
  • @Flyte if you want something that will run when you quit IPython, you can do what the original question was trying, and use [atexit](https://docs.python.org/3/library/atexit.html). – Thomas K Jan 22 '16 at 21:25
  • @ThomasK Yes, but the problem is that IPython doesn't call it on exit. – Ellis Percival Jan 23 '16 at 20:24
  • @Flyte I've just [checked](http://pastebin.com/LQJc1E7c), and it does get called. IPython doesn't need to call it - it happens automatically when the Python interpreter exits. Are you using IPython embedded in something else? – Thomas K Jan 23 '16 at 21:30
  • @ThomasK No, I was trying to use atexit to close a serial port because it hangs on exit otherwise. Using atexit didn't work, so I guess it hangs before IPython calls the atexit function. Never mind, I'll just write s.close() at the end of every session :) – Ellis Percival Jan 23 '16 at 22:19