How to break from `__main__` without exit() - python

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()

Related

Script guard without indenting execution code

if __name__ == '__main__': prevents any code beneath it from executing in any non-main script (e.g. imports) - however, it requires all pertinent code to be indented. Is there an alternative to not executing code beneath that line, without indenting said code?
if __name__ != '__main__':
sys.exit(0)
do_stuff() # <-- NOT indented
Something like above, except without terminating the entire program.
It sounds like you're asking for either a "stop importing here" statement or a clean way to avoid Python's rules about indentation. No, neither are feasible. If you don't want do_stuff() to be executed at import time, your choices are to put it under the if block or to comment it out or to remove it from the file.

Solution to get output for python project

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)

Python: what is the difference between an explicit exit and simply letting execution reach the end of the file?

For a simple python script that doesn't start any threads or fork any processes, what's the difference between simply letting execution reach the end of the script and explicitly calling quit(), exit(), or sys.exit()?
i.e. what's the difference between
def main():
# do some stuff
print("Done doing stuff")
if __name__ == '__main__':
main()
and
import sys
def main():
# do some stuff
print("Done doing stuff")
# explicit exit
sys.exit()
if __name__ == '__main__':
main()
I'm asking this because I have been having some odd garbage collection issues on script termination (exceptions raised from __del__ apparently due to the order in which things get cleaned up) without the explicit exit() call, and adding an explicit exit() appears to correct those issues. Or at least none of those exceptions get printed after calling exit(), maybe they are simply being silenced.
In the case you have posted, there is no difference. But the are cases in which you may want to terminate your program without waiting for it to finish.
A banal example:
try:
...
except KeyboardInterrupt:
x = input('Sure you want to exit? y/n')
if x == 'y':
quit()
else:
pass

Re-run script in Python 3.5

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!

run a python program on a new thread

I have two programs
program1.py is like commandline interface which takes command from user
program2.py has the program which runs the relevant program as per the command.
Program 1 has also has an quit_program() module
In our simple universe.. lets say I have just one command and just one program
So lets say...
program1.py
def main():
while True:
try:
command = raw_input('> ')
if command == "quit" :
return
if command == '':
continue
except KeyboardInterrupt:
exit()
parseCommand(command)
And then I have:
if commmand == "hi":
say_hi()
Now program2 has
def say_hi():
#do something..
Now there can be two cases...
Either say_hi() completes in which case no issue...
But what i want is that if user enters a command (say: end)
then this say_hi() is terminated in between..
But my current implementation is very sequential.. I mean I dont get to type anything on my terminal untill the execution is completed..
Somethng tells me that the say_hi() should be running on another thread?
I am not able to think straight about this.
Any suggestions?
Thanks
The threading module is what you are looking for.
import threading
t = threading.Thread(target=target_function,name=name,args=(args))
t.daemon = True
t.start()
The .daemon option makes it so you don't have to explicitly kill threads when your app exits... Threads can be quite nasty otherwise
Specific to this question and the question in the comments, the say_hi function can be called in another thread as such:
import threading
if commmand == "hi":
t = threading.Thread(target=say_hi, name='Saying hi') #< Note that I did not actually call the function, but instead sent it as a parameter
t.daemon = True
t.start() #< This actually starts the thread execution in the background
As a side note, you must make sure you are using thread safe functions inside of threads. In the example of saying hi, you would want to use the logging module instead of print()
import logging
logging.info('I am saying hi in a thread-safe manner')
You can read more in the Python Docs.

Categories

Resources