# [Python] 例外執行順序 ###### tags: `python` :::info * break、return、raise都會使程序跳出try/except/finally對應的區塊 * finally的區塊總是在整個try/except之後執行 * return的結果可以被覆蓋 * 函數的返回值在finally之後才"返回" * Exception是BaseException的子類別,可以捕捉除了系統例外以外的所有例外,也就可以藉由KeyboardInterrupt中斷迴圈。 ::: try finally break return raise ```python= def test(): try: int("TEST") return "try" except Exception as error: print("Before raise") return "except" raise ValueError from error print("After raise") finally: print("Finally") return "finally" print("return: ", test()) ===output=== Before raise Finally return: finally ``` finally即使是在return的情況下依然會執行,甚至可以覆蓋return的結果! ```python= def test(): try: int("TEST") return "try" except Exception as error: print("Before raise") raise ValueError from error print("After raise") return "except" finally: print("Finally") return "finally" print("return: ", test()) ===output=== Before raise Finally return: finally ``` 不管使用raise或return都會立即跳出該區塊! 而raise拋出的順序會在finally執行之後,但是遇到return就不執行。 ``` 註解 # return "finally" ===output=== Before raise Finally --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-21-34cfccebe447> in test() 2 try: ----> 3 int("TEST") 4 return "try" ValueError: invalid literal for int() with base 10: 'TEST' The above exception was the direct cause of the following exception: ValueError Traceback (most recent call last) <ipython-input-21-34cfccebe447> in <module>() 12 # return "finally" 13 ---> 14 print("return: ", test()) <ipython-input-21-34cfccebe447> in test() 5 except Exception as error: 6 print("Before raise") ----> 7 raise ValueError from error 8 print("After raise") 9 return "except" ValueError: ``` ```python= i = 0 while True: try: if i == 0: print("break") break except Exception: print("except") finally: print("finally") ===output=== break finally ``` ```python= def test_return(i): while True: try: if i == 0: print("return") return i except Exception: print("except") finally: print("finally") print("return: ", test_return(0)) ===output=== return finally return: 0 ``` ```python= import sys try: raise EOFError except: type_, message, traceback = sys.exc_info() print(type_) print(message) print(traceback) ===output=== <class 'EOFError'> <traceback object at 0x000001E526C17048> ``` ```python= try: try: raise EOFError('EOFError') except EOFError as e: print(e.args) raise IndexError('IndexError') from e except IndexError as e: print(e.args) print(e.__cause__.args) print(e.__context__.args) ===output=== ('EOFError',) ('IndexError',) ('EOFError',) ('EOFError',) ``` raise from語法,會將from後接上的例外實例,設定給被raise的例外實例之__cause__。 實際上,如果你在except中raise某個例外,則原except所比對到的例外,無論有無使用raise from,都會自動設定給__context__。 ## 參考 [實作執行情況(1)](https://www.jianshu.com/p/343fe0942b80) [實作執行情況(2)](https://openhome.cc/Gossip/Python/TryRaise.html)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up