views:

82

answers:

2

I have a python program that runs a cell model continuously. when I press "A" or "B" certain functions are called - cell divide, etc. when the "esc" key is pressed the simulation exits. Is there a way for the program to exit and then restart itself when "esc" is pressed?

A: 

The obvious solution is for the program to start a new copy of itself as the last thing it does before exiting. But you probably should think more along the lines of coding the simulator so that it can be reset without requiring a complete restart of the program.

Marcelo Cantos
but if i call the program in the background, will my key press be passed to it? and if i call it normally, won't the last simulation keep running too?
blank bank
+1  A: 

Yes. This is probably what you want

The-Evil-MacBook:~ ivucica$ cat test.py
#!/usr/bin/env python
import sys
import os
print sys.argv[0] + " with argcount " + str(len(sys.argv))
if len(sys.argv) < 2 or sys.argv[1] != "2":
    print "doing recursion"
    os.system(sys.argv[0] + " 2");
else:
    print "not doing recursion"

exit(0)
The-Evil-MacBook:~ ivucica$ ./test.py
./test.py with argcount 1
doing recursion
./test.py with argcount 2
not doing recursion
The-Evil-MacBook:~ ivucica$ 

So when you want the program to restart itself, just call its sys.argv[0] using os.system() and immediately call exit(some_return_code_here) (zero means 'no error'). You might want to pass an extra argument so it knows it's a restarted instance, but are by no means required to do so; I did so above to prevent endless loop. If you have other mechanisms to prevent endless loops, then use those.

Please also note: for the above code, you need to run the program directly; python test.py did not do the trick for me (for obvious reasons). Also, above will probably work only under UNIX systems.

Note, also, that system() is blocking. If you need the original program to complete shutdown upon launching new program, easiest way would be to send the new one into background (thus "unblocking" system()). Just modify the line like this:

    os.system(sys.argv[0] + " 2 &");

Note the "&" which tells the shell to send the new process into background.

Ivan Vučica
Do you end up with the original (parent) process waiting for the child process to end before it ends itself? That won't be so good if you're repeating this action a large number of times.
Adrian Pronk
Ivan Vučica
Maybe (on UNIXoid systems, at least) you could consider EXEC which does not have this problem. I'm not familiar with Python, but in Perl it is just as easy to use.
Adrian Pronk
Sure; one could fork() and exec() in C. I just wanted to answer in the easiest way possible, without looking up how to do that in Python.
Ivan Vučica