A try statement can have four parts. Each one runs at a different time:
try: the code that might fail.except: runs only if that code raised a matching exception.else: runs only if thetryblock finished with no exception.finally: always runs, error or not. It is the place to clean up, for example to close a file.
The program
python
# create two sample files for this example with open("good.txt", "w") as f: f.write("42\n") with open("bad.txt", "w") as f: f.write("forty-two\n") def read_number(filename): print(f"[{filename}]") file = None try: file = open(filename) number = int(file.read()) except FileNotFoundError: print(" except: the file does not exist") except ValueError: print(" except: the file does not contain a whole number") else: print(f" else: the number is {number}") finally: if file is not None: file.close() print(" finally: file closed") else: print(" finally: no file to close") read_number("good.txt") read_number("bad.txt") read_number("missing.txt")
output
[good.txt] else: the number is 42 finally: file closed [bad.txt] except: the file does not contain a whole number finally: file closed [missing.txt] except: the file does not exist finally: no file to close
How it works
- For
good.txtnothing fails, so bothexceptblocks are skipped,elseruns, and thenfinallyruns. - For
bad.txtthe file opens, butint("forty-two\n")raises aValueError. TheValueErrorblock runs,elseis skipped, andfinallystill closes the file. - For
missing.txt,open()itself fails, sofileis stillNoneand there is nothing to close. That is whyfile = Noneis set before thetry. - Why use
elseinstead of putting the print insidetry? Code inelseis not protected by theexceptblocks. Keep thetryblock short, so that you only catch errors from the lines you expect to fail.
For files, a with block closes the file for you, so in real code you rarely need finally for this. The context manager program shows how with works. finally is still useful for other clean-up, such as closing a network connection or a database.
finally runs even after return
finally runs even when the try block leaves the function with return:
python
def check(): try: print("try: about to return") return "the return value" finally: print("finally: runs before the function returns") print(check())
output
try: about to return finally: runs before the function returns the return value
Related programs: try except example.