I want to make my program recursively call itself, so I tried this. However, for some reason even though the code does execute I get the desired effect only in Pycharms debugger. Any ideas?
os.execv(sys.executable, [sys.executable, file] + sys.argv)
Note: I don't really need to pass any arguments to the new iteration
In my code I have an object called mcp. When this objects internal state changes to restart I need to start the main function all over again. Note that the internal state of the system is correct. I managed to work around it by using os.system("")
if __name__ == "__main__":
mcp = Mcp()
mcp.start()
while mcp.internal_state == State.Running.value:
time.sleep(1)
if mcp.internal_state == State.ShutDown.value or mcp.internal_state == State.Restart.value:
mcp.wait()
if mcp.internal_state == State.Restart.value:
#os.execv(sys.executable, [sys.executable, __file__] + sys.argv)
os.system("Python rinzler.py")
Related
I wrote a app that restarts explorer.exe but the problem is that after i re-open explorer.exe it should call the main function again, but it doesn't.
The 'funny' stuff that i found is that if i dont open explorer.exe, the main function will be called as it should.
import os
def sendCmd(command):
return os.system(command)
# Main function
def Main():
sendCmd('cls')
q = input() # Checks for input
if q == "1": # If the option 1 is selected
sendCmd("taskkill /f /im explorer.exe") # Kills explorer
sendCmd("explorer.exe") # Opens explorer
Main()
Thanks!
nice question, my guess is that python uses the main thread when explorer.exe is open so it is not going forward to the Main() function and does not do that command. try to close explorer.exe manually and check if the program calls the main function.
Anyway, To solve that you can call the sendCmd("explorer.exe") in another thread and your program will continue to the Main() line (I would use while True in this case instead of recursion https://www.geeksforgeeks.org/difference-between-recursion-and-iteration/)
th = threading.Thread(target=sendCmd, args=('explorer.exe', ))
# Start the thread
th.start()
I'm doing python coding with Emacs.
I find it troublesome to get Emacs inferior shell exited whenever I call sys.exit. How can the code break from __main__ block without killing Emacs inferior shell process, without introducing another indented block?
if __name__ == "__main__":
# doing something
if args.init:
init_env(cfg_dict, args)
exit(0) # <--- this kills the Emacs sub-shell
# otherwise doing something
# ...
P.S. I slept on the title of this question for a while, but I couldn't think of better title. :-(
Why not wrap the main code in a function and make use of return:
def main():
# doing something
if args.init:
init_env(cfg_dict, args)
return
if __name__ == "__main__":
main()
I am doing a simple project on my Pycharm IDE.
My code is this:
import webbrowser
import time
socialMediaUrls = ["www.google.com","www.edureka.com"]
techUrls = ["www.udacity.com","www.dailymotion.com"]
def open_tabs(url_list):
for element in url_list:
webbrowser.open_new_tab(element)
def main():
webbrowser.open("www.youtube.com",new=0,autoraise=false)
time.sleep(1)
open.tab(socialMedialUrls)
open_tabs(techUrls)
main()
but after running I am getting this message:
C:\Users\adc\AppData\Local\Programs\Python\Python36-32\python.exe
C:/Users/adc/PycharmProjects/untitled1/ur.py
Process finished with exit code 0
And I am getting same message for all my projects. What should I do?
You should call main in that way:
def main():
webbrowser.open("www.youtube.com",new=0,autoraise=false)
time.sleep(1)
open.tab(socialMedialUrls)
open_tabs(techUrls)
if __name__ == "__main__":
main()
Also I see that your code contains some other errors. For example, in Python there is False keyword, not false. Lines with open.tab and open_tabs will not work too.
Currently, no instructions are reachable in your script (besides the import statements)
in:
def main():
webbrowser.open("www.youtube.com",new=0,autoraise=false)
time.sleep(1)
open.tab(socialMedialUrls)
open_tabs(techUrls)
main()
indentation suggests that you're performing a recursive call (which isn't what you want).
Unindent main() to make sure you execute something in your script.
Or put the instructions of main at zero-indent level outside any procedure (in that case, it is executed even when importing the module, probably not important here)
(note that python programs don't need a main(), this isn't C)
How do I get main to run again without executing the whole script again?
import sys #importing module that is used to exit the script
def main ():
#doing stuff
main ()
#Re-run the script - looking for a cleaner way to do this!
def restart ():
restart = input("Press any key + Enter to start again, or x + Enter to exit.")
if(restart != "x"):
exec(open("./calc.py").read())
# not sure how to run main() again without calling out the script name again?
else:
print ("Exiting!")
sys.exit ((main))
restart ()
#End of Program
You can re-run the main module-method as many times as you want by directly calling main() sequentially:
def main( ):
# Code goes here...
return;
main();
main();
main();
However, if you want the user-interaction like your restart method has, you might want to consider defining main with an optional parameter (one that has a default value) that controls whether you ask to re-run the method or not.
def main( argv, AskRestart= True ):
# Main code goes here....
if ( AskRestart ):
# User interaction code goes here ...
return;
Also, you can look into the atexit package in Python 3.5.1 to see how you can assign a method to be run only when exiting the interpreter:
https://docs.python.org/3.5/library/atexit.html
That would allow you to do whatever you want and then when everything is done, give someone the option of restarting the entire module. This would remove the reliance on the exec call, and be a more coherent and simpler approach to getting the exact same expected functionality.
In addition to Tommy's great advice, (I'm not sure of your goal in continually restarting main() as main is an empty function that doesn't do anything yet, but..) one way to have main continually repeat until the user enters x may be to use a while True loop:
import sys #importing module that is used to exit the script
def main ():
#doing stuff
restart() # <-- use main to restart()
#Re-run the script - looking for a cleaner way to do this!
def restart ():
restart = raw_input("Press any key + Enter to start again, or x + Enter to exit.")
while True: # <-- key to continually restart main() function
if(restart != "x"):
exec(open("./calc.py").read())
# not sure how to run main() again without calling out the script name again?
main() # <-- restart main
else:
print ("Exiting!")
sys.exit ((main))
restart ()
#End of Program
Hope this also helps!
I have written a script that will keep itself up to date by downloading the latest version from a website and overwriting the running script.
I am not sure what the best way to restart the script after it has been updated.
Any ideas?
I don't really want to have a separate update script.
oh and it has to work on both linux/windows too.
In Linux, or any other form of unix, os.execl and friends are a good choice for this -- you just need to re-exec sys.executable with the same parameters it was executed with last time (sys.argv, more or less) or any variant thereof if you need to inform your next incarnation that it's actually a restart. On Windows, os.spawnl (and friends) is about the best you can do (though it will transiently take more time and memory than os.execl and friends would during the transition).
The CherryPy project has code that restarts itself. Here's how they do it:
args = sys.argv[:]
self.log('Re-spawning %s' % ' '.join(args))
args.insert(0, sys.executable)
if sys.platform == 'win32':
args = ['"%s"' % arg for arg in args]
os.chdir(_startup_cwd)
os.execv(sys.executable, args)
I've used this technique in my own code, and it works great. (I didn't bother to do the argument-quoting step on windows above, but it's probably necessary if arguments could contain spaces or other special characters.)
I think the best solution whould be something like this:
Your normal program:
...
# ... part that downloaded newest files and put it into the "newest" folder
from subprocess import Popen
Popen("/home/code/reloader.py", shell=True) # start reloader
exit("exit for updating all files")
The update script: (e.g.: home/code/reloader.py)
from shutil import copy2, rmtree
from sys import exit
# maybie you could do this automatic:
copy2("/home/code/newest/file1.py", "/home/code/") # copy file
copy2("/home/code/newest/file2.py", "/home/code/")
copy2("/home/code/newest/file3.py", "/home/code/")
...
rmtree('/home/code/newest') # will delete the folder itself
Popen("/home/code/program.py", shell=True) # go back to your program
exit("exit to restart the true program")
I hope this will help you.
The cleanest solution is a separate update script!
Run your program inside it, report back (when exiting) that a new version is available. This allows your program to save all of its data, the updater to apply the update, and run the new version, which then loads the saved data and continues. To the user this can be completely transparent, as they just run the updater-shell which runs the real program.
To additionally support script calls with Python's "-m" parameter the following can be used (based on the Alex's answer; Windows version):
os.spawnl(os.P_WAIT, sys.executable, *([sys.executable] +
(sys.argv if __package__ is None else ["-m", __loader__.name] + sys.argv[1:])))
sys.exit()
Main File:
if __name__ == '__main__':
if os.path.isfile('__config.py'):
print 'Development'
push.update_server()
else:
e = update.check()
if not e: sys.exit()
Update File:
def check():
e = 1.....perform checks, if something needs updating, e=0;
if not e:
os.system("python main.pyw")
return e
Here's the logic:
Main program calls the update function
1) If the update function needs to update, than it updates and calls a new instances of "main"
Then the original instance of "main" exits.
2) If the update function does not need to update, then "main" continues to run
Wouldn't it just be easier to do something like
Very simple, no extra imports needed, and compatible with any OS depending on what you put in the os.system field
def restart_program():
print("Restarting Now...")
os.system('your program here')
You can use reload(module) to reload a module.