代码之家  ›  专栏  ›  技术社区  ›  Fomalhaut

如何在Python 3中停止exec命令内部的执行?

  •  3
  • Fomalhaut  · 技术社区  · 6 年前

    我有以下代码:

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

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

    如何强迫 exec 停止而不出错?也许我该换个 return 带着什么?我还想让翻译在 执行官

    4 回复  |  直到 5 年前
        1
  •  2
  •   Aran-Fey Swapnil    5 年前

    在这里,就这样做:

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

        2
  •  1
  •   Aran-Fey Swapnil    5 年前

    这将起作用,返回仅在定义的函数中起作用:

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

    code = """
    def func():
        print("foo")
    
        if True: 
            return
    
        print("bar")
    
    func()    
    """
    exec(code)
    print('This should still be executed')
    
        3
  •  1
  •   Aran-Fey Swapnil    5 年前

    没有内置机制允许您中止 exec 打电话来。我们最接近的是 sys.exit() ,但这会退出整个程序,而不仅仅是 执行官 . 幸运的是,这可以通过少量的异常处理样板来解决:

    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
  •  1
  •   Amadan    5 年前

    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