Stop execution of a script called with execfile
Asked Answered
F

3

17

Is it possible to break the execution of a Python script called with the execfile function without using an if/else statement? I've tried exit(), but it doesn't allow main.py to finish.

# main.py
print "Main starting"
execfile("script.py")
print "This should print"

# script.py
print "Script starting"
a = False

if a == False:
    # Sanity checks. Script should break here
    # <insert magic command>    

# I'd prefer not to put an "else" here and have to indent the rest of the code
print "this should not print"
# lots of lines below
Fecund answered 22/6, 2009 at 17:58 Comment(3)
Why are you using execfile() and not import?Ocam
I think execfile allows for more flexibility when I am editing the scripts in a separate window and executing them on the flyFecund
Also Spyder uses execfile(), so this quesiton is relevant to anyone who wants to end their script but keep the console alive afterwards.Sulky
G
22

main can wrap the execfile into a try/except block: sys.exit raises a SystemExit exception which main can catch in the except clause in order to continue its execution normally, if desired. I.e., in main.py:

try:
  execfile('whatever.py')
except SystemExit:
  print "sys.exit was called but I'm proceeding anyway (so there!-)."
print "so I'll print this, etc, etc"

and whatever.py can use sys.exit(0) or whatever to terminate its own execution only. Any other exception will work as well as long as it's agreed between the source to be execfiled and the source doing the execfile call -- but SystemExit is particularly suitable as its meaning is pretty clear!

Grandstand answered 22/6, 2009 at 18:4 Comment(4)
That seems like a hack to me. Though Python is an exception-friendly language...Massarelli
Exiting early from linear code requires one of return, continue, break, or raise (sys.exit() being a special case of raise). raise is the least hackish in this context, IMO.Finland
@Matthew, I agree with @Rick: in Python, exceptions aren't that exceptional (there's one, StopIteration, at the normal end of every for loop, for example!), so using one to terminate the exec'd-file execution seems acceptable to me.Grandstand
BTW, just to add more info: if you call quit(), it will also raise SystemExit and give the same message. Not if you call os._exit().Marshy
M
4
# script.py
def main():
    print "Script starting"
    a = False

    if a == False:
        # Sanity checks. Script should break here
        # <insert magic command>    
        return;
        # I'd prefer not to put an "else" here and have to indent the rest of the code
    print "this should not print"
    # lots of lines bellow

if __name__ ==  "__main__":
    main();

I find this aspect of Python (the __name__ == "__main__", etc.) irritating.

Massarelli answered 22/6, 2009 at 18:2 Comment(3)
There are two small errors in the code you posted: "print "this should not print"" is indented one too much and return does not need a semicolon. Thanks, I think I'll use this.Fecund
But then the lines are indented, which is what the OP wants to avoid. I don't understand why that indenting is to be avoided, though.Digit
I fixed the print. I'm keeping the semi-colon though. ;) Ah, how I hate significant whitespace. :)Massarelli
P
1

What's wrong with plain old exception handling?

scriptexit.py

class ScriptExit( Exception ): pass

main.py

from scriptexit import ScriptExit
print "Main Starting"
try:
    execfile( "script.py" )
except ScriptExit:
    pass
print "This should print"

script.py

from scriptexit import ScriptExit
print "Script starting"
a = False

if a == False:
    # Sanity checks. Script should break here
    raise ScriptExit( "A Good Reason" )

# I'd prefer not to put an "else" here and have to indent the rest of the code
print "this should not print"
# lots of lines below
Placard answered 22/6, 2009 at 20:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.