gpt4 book ai didi

python - 'finally' 是否总是在 Python 中执行?

转载 作者:IT老高 更新时间:2023-10-28 21:06:00 25 4
gpt4 key购买 nike

对于Python中任何可能的try-finally block ,是否保证finally block 总是会被执行?

例如,假设我在 except block 中返回:

try:
1/0
except ZeroDivisionError:
return
finally:
print("Does this code run?")

或者我可能会重新引发 Exception:

try:
1/0
except ZeroDivisionError:
raise
finally:
print("What about this code?")

测试表明 finally 确实会为上述示例执行,但我想还有其他我没有想到的场景。

是否存在 finally block 在 Python 中无法执行的情况?

最佳答案

“Guaranteed”这个词比任何 finally 的实现都强得多。可以保证的是,如果执行流出整个 try-finally 构造,它将通过 finally 执行。不保证的是执行会流出try-finally

  • A finally in a generator or async coroutine might never run , 如果对象永远不会执行到结论。有很多可能发生的方式;这是一个:

    def gen(text):
    try:
    for line in text:
    try:
    yield int(line)
    except:
    # Ignore blank lines - but catch too much!
    pass
    finally:
    print('Doing important cleanup')

    text = ['1', '', '2', '', '3']

    if any(n > 1 for n in gen(text)):
    print('Found a number')

    print('Oops, no cleanup.')

    请注意,这个例子有点棘手:当生成器被垃圾回收时,Python 尝试通过抛出 GeneratorExit 异常来运行 finally block ,但在这里我们捕获该异常,然后再次 yield,此时 Python 会打印一个警告(“生成器忽略 GeneratorExit”)并放弃。见 PEP 342 (Coroutines via Enhanced Generators)了解详情。

    生成器或协程可能无法执行到结论的其他方式包括:如果对象从未被 GC 处理(是的,即使在 CPython 中也是可能的),或者如果 async with awaits 在 __aexit__ 中,或者对象 awaits 或 yields 在 finally block 中.此列表并非详尽无遗。

  • A finally in a daemon thread might never execute如果所有非守护线程先退出。

  • os._exit will halt the process immediately不执行 finally block 。

  • os.fork 可能会导致 finally block 到 execute twice .除了发生两次事情会出现的正常问题外,如果对共享资源的访问不是 correctly synchronized,这可能会导致并发访问冲突(崩溃、停顿等)。 .

    由于 multiprocessing 在使用 fork start method 时使用 fork-without-exec 来创建工作进程(Unix默认),然后在worker的工作完成后调用os._exitfinallymultiprocessing交互即可有问题(example)。

  • C 级段错误将阻止 finally block 运行。
  • kill -SIGKILL 将阻止 finally block 运行。 SIGTERMSIGHUP 也会阻止 finally block 运行,除非你自己安装一个处理程序来控制关机;默认情况下,Python 不处理 SIGTERMSIGHUP
  • finally 中的异常会阻止清理完成。一个特别值得注意的情况是,如果用户在我们开始执行 finally block 时点击了 control-C just。 Python 将引发 KeyboardInterrupt 并跳过 finally block 内容的每一行。 (KeyboardInterrupt——安全代码很难写)。
  • 如果计算机断电,或者如果它休眠并且没有唤醒,finally block 将不会运行。

finally block 不是交易系统;它不提供原子性保证或任何类似的保证。其中一些示例可能看起来很明显,但很容易忘记此类事情可能发生并过度依赖 finally

关于python - 'finally' 是否总是在 Python 中执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49262379/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com