Khối finally trong cấu trúc try/except/finally luôn được thực thi, bất kể có exception hay không. Dùng cho dọn dẹp tài nguyên (đóng file, connection...).
Cú pháp
try:
# Code có thể gây exception
except SomeException:
# Xử lý exception (tùy chọn)
finally:
# Luôn chạy - cleanup code
Ví dụ 1: Có exception, có xử lý
try:
var1 = 'Tutorials'
print(var2) # NameError: var2 không định nghĩa
except NameError:
print("Biến không tồn tại trong scope")
finally:
print("Finally block luôn chạy")
Kết quả
Biến không tồn tại trong scope Finally block luôn chạy
Ví dụ 2: Có exception, KHÔNG xử lý (unhandled)
try:
var1 = 'Tutorials'
print(var2) # NameError
finally:
print("Finally block vẫn chạy trước khi crash")
Kết quả
Finally block vẫn chạy trước khi crash Traceback (most recent call last): File "...", line 3, inprint(var2) NameError: name 'var2' is not defined
Ví dụ 3: Không có exception
try:
x = 10 / 2
print(f"Kết quả: {x}")
finally:
print("Cleanup: đóng file, connection...")
Kết quả
Kết quả: 5.0 Cleanup: đóng file, connection...
Ứng dụng thực tế: Quản lý tài nguyên
def read_file_safe(filename):
f = None
try:
f = open(filename, 'r')
content = f.read()
return content
except FileNotFoundError:
print(f"File {filename} không tồn tại")
return None
finally:
if f:
f.close() # Luôn đóng file
print("File đã được đóng")
# Hoặc tốt hơn: dùng context manager (with)
def read_file_modern(filename):
try:
with open(filename, 'r') as f:
return f.read()
except FileNotFoundError:
print(f"File {filename} không tồn tại")
return None
# with tự động đóng file, không cần finally
Kết luận
finally đảm bảo code cleanup chạy mọi trường hợp. Tuy nhiên, ưu tiên with statement (context manager) cho file, lock, connection - an toàn và gọn hơn.