tags:

views:

339

answers:

2

I'm writing a Python program that, if the user changes settings while running it, needs to be restarted to apply the changed settings. Is there a way of doing this? I'm thinking something along the lines of:

import sys
command_line = ' '.join(sys.argv)
# Now do something with command_line
# Now call my custom exit procedure

Note: I'm on Windows, if that makes a difference

+3  A: 

I would bypass all the angst you're likely to get from trying to re-run yourself and leave it in the hands of the environment.

By that, I mean:

  1. Have a controlling program which does nothing more than run your program (with the same parameters it was given) in a loop while your program exits with a specific "restart" code. This could be as simple as a cmd file or as complex as another (very simple) Python program that uses os.system). Basically, as long as the controlling program gets the code "restart", it will re-run your program with exactly the same parameters. Any other code will cause it to exit with that code.

  2. When you want to exit fully, have your real Python program exit with return code 0 (or anything that's not the "restart" code in an error situation).

  3. If you just want to cycle to another iteration of your program (to re-read the config for example), exit with the "restart" code recognised by the controlling program.

But you may also want to think about re-engineering your application so that it can re-read its configuration at any time. This will make the whole problem go away. You don't mention why that's not an option so I'm assuming you have some reason why it won't work.

But, if you don't, that's the path I'd be choosing.

To provide some sample code for the first option (this is on Windows but under Cygwin - the same basic rules should apply for Windows native Python but you should check the return values from os.system).:

> cat phase1.py
#!/usr/bin/python
import os
status = 9
while status == 9:
    status = int(os.system ("./phase2.py") / 256) # exit code is upper 8 bits
    print "Controller: %d"%(status)

 

> cat phase2.py
#!/usr/bin/python
import sys
import time
time.sleep(1)
val = int(time.time())%10
if val == 0:
    rc = 0
else:
    rc = 9
print "Program: %d -> %d"%(val,rc)
sys.exit(rc)

 

> ./phase1.py
Program: 2 -> 9
Controller: 9
Program: 3 -> 9
Controller: 9
Program: 4 -> 9
Controller: 9
Program: 5 -> 9
Controller: 9
Program: 7 -> 9
Controller: 9
Program: 8 -> 9
Controller: 9
Program: 9 -> 9
Controller: 9
Program: 0 -> 0
Controller: 0

You can see the controller using an exit code of 9 to decide whether to re-run the program. The program itself is a dumb one which returns 9 unless it's on a 10-second multiple.

paxdiablo
+1  A: 

On unix, you can use os.execl family of functions:

These functions all execute a new program, replacing the current process; they do not return. On Unix, the new executable is loaded into the current process, and will have the same process id as the caller. Errors will be reported as OSError exceptions.

On windows, take a look at the os.spawnl family, which are less efficient than the unix calls.

ars