Does 'finally' always execute in Python?

前端 未结 6 2066
眼角桃花
眼角桃花 2021-01-29 21:38

For any possible try-finally block in Python, is it guaranteed that the finally block will always be executed?

For example, let’s say I return while in an <

6条回答
  •  野的像风
    2021-01-29 22:12

    I found this one without using a generator function:

    import multiprocessing
    import time
    
    def fun(arg):
      try:
        print("tried " + str(arg))
        time.sleep(arg)
      finally:
        print("finally cleaned up " + str(arg))
      return foo
    
    list = [1, 2, 3]
    multiprocessing.Pool().map(fun, list)
    

    The sleep can be any code that might run for inconsistent amounts of time.

    What appears to be happening here is that the first parallel process to finish leaves the try block successfully, but then attempts to return from the function a value (foo) that hasn't been defined anywhere, which causes an exception. That exception kills the map without allowing the other processes to reach their finally blocks.

    Also, if you add the line bar = bazz just after the sleep() call in the try block. Then the first process to reach that line throws an exception (because bazz isn't defined), which causes its own finally block to be run, but then kills the map, causing the other try blocks to disappear without reaching their finally blocks, and the first process not to reach its return statement, either.

    What this means for Python multiprocessing is that you can't trust the exception-handling mechanism to clean up resources in all processes if even one of the processes can have an exception. Additional signal handling or managing the resources outside the multiprocessing map call would be necessary.

提交回复
热议问题