How do I stop execution inside exec command in Pyt

2020-04-07 19:52发布

问题:

I have a following code:

code = """
print("foo")

if True: 
    return

print("bar")
"""

exec(code)
print('This should still be executed')

If I run it I get:

Traceback (most recent call last):
  File "untitled.py", line 10, in <module>
    exec(code)
  File "<string>", line 5
SyntaxError: 'return' outside function

How to force exec stop without errors? Probably I should replace return with something? Also I want the interpreter work after exec call.

回答1:

Here, just do something like this:

class ExecInterrupt(Exception):
    pass

def Exec(source, globals=None, locals=None):
    try:
        exec(source, globals, locals)
    except ExecInterrupt:
        pass

Exec("""
print("foo")

if True: 
    raise ExecInterrupt

print("bar")
""")
print('This should still be executed')

If your worry is readability, functions are your first line of defense.



回答2:

This will work, return only works from within a defined function:

code = """
print("foo")

if not True:
    print("bar")
"""
exec(code)
print('This should still be executed')

but if you want to use return, you must do something like:

code = """
def func():
    print("foo")

    if True: 
        return

    print("bar")

func()    
"""
exec(code)
print('This should still be executed')


回答3:

There is no built-in mechanism that allows you to abort execution of an exec call. The closest thing we have is sys.exit(), but that exits the whole program, not just the exec. Fortunately, this can be worked around with a minor amount of exception handling boilerplate:

my_code = """
import sys

print("foo")

if True: 
    sys.exit()

print("bar")
"""

try:
    exec(my_code)
except SystemExit:
    pass
print('This is still executed')

# output:
# foo
# This is still executed


回答4:

Just for fun, here's another way:

def breakable_exec(code):
    exec('for _ in [0]:' + '\n'.join("    " + line for line in code.splitlines()))

code = """
print("foo")

if True: 
    break

print("bar")
"""

breakable_exec(code)
# => foo


标签: python exec