Xử lý ngoại lệ Python
Category: Python
Python Exception Handling xử lý lỗi xảy ra trong quá trình thực thi chương trình. Exception handling cho phép phản hồi lỗi, thay vì làm sập chương trình đang chạy. Nó cho phép bạn bắt và quản lý lỗi, giúp mã của bạn mạnh mẽ hơn và thân thiện với người dùng hơn. Hãy xem một ví dụ:
Xử lý một ngoại lệ đơn giản trong Python
Xử lý ngoại lệ giúp ngăn ngừa sự cố do lỗi. Sau đây là một ví dụ cơ bản minh họa cách bắt ngoại lệ và xử lý nó một cách khéo léo:
# Ví dụ xử lý ngoại lệ đơn giản
n = 10
try:
res = n / 0 # Điều này sẽ gây ra lỗi ZeroDivisionError
except ZeroDivisionError:
print("Can't be divided by zero!")
Đầu ra:
Can't be divided by zero!
Giải thích: Trong ví dụ này, chia số cho 0 sẽ gây ra lỗi ZeroDivisionError . Khối try chứa mã có thể gây ra ngoại lệ và khối except xử lý ngoại lệ, in thông báo lỗi thay vì dừng chương trình.
Sự khác biệt giữa Exception và Error
Lỗi : Lỗi là những vấn đề nghiêm trọng mà một chương trình không nên cố gắng xử lý. Chúng thường là các vấn đề trong logic hoặc cấu hình của mã và cần được lập trình viên sửa. Ví dụ bao gồm lỗi cú pháp và lỗi bộ nhớ.
Ngoại lệ : Ngoại lệ ít nghiêm trọng hơn lỗi và có thể được xử lý bởi chương trình. Chúng xảy ra do các tình huống như đầu vào không hợp lệ, thiếu tệp hoặc sự cố mạng.
Ví dụ:
# Lỗi cú pháp (Syntax Error)
print("Hello world" # Thiếu dấu ngoặc đơn đóng
# Ngoại lệ (ZeroDivisionError)
n = 10
res = n / 0
Giải thích: Lỗi cú pháp là lỗi mã hóa ngăn không cho mã chạy. Ngược lại, ngoại lệ như ZeroDivisionError có thể được quản lý trong quá trình thực thi chương trình bằng cách xử lý ngoại lệ.
Cú pháp và cách sử dụng
Xử lý ngoại lệ trong Python được thực hiện bằng các khối try, except, else và finally.
thử:
# Mã có thể gây ra ngoại lệ ngoại
trừ SomeException:
# Mã để xử lý ngoại lệ
else:
# Mã để chạy nếu không có ngoại lệ nào xảy ra
finally:
# Mã để chạy bất kể có ngoại lệ xảy ra hay không
thử, ngoại trừ, khác và cuối cùng Khối
Khối try : khối try cho phép chúng ta kiểm tra một khối mã để tìm lỗi. Python sẽ "thử" thực thi mã trong khối này. Nếu xảy ra ngoại lệ, việc thực thi sẽ ngay lập tức nhảy đến khối except.
except Block: except block cho phép chúng ta xử lý lỗi hoặc ngoại lệ. Nếu mã bên trong khối try ném ra lỗi, Python sẽ nhảy đến khối except và thực thi lỗi đó. Chúng ta có thể xử lý các ngoại lệ cụ thể hoặc sử dụng except chung để bắt tất cả các ngoại lệ.
else Block: else block là tùy chọn và nếu được bao gồm, phải theo sau tất cả các except block. else block chỉ chạy nếu không có ngoại lệ nào được đưa ra trong try block. Điều này hữu ích cho mã sẽ được thực thi nếu try block thành công.
finally Block: finally block luôn chạy, bất kể có xảy ra ngoại lệ hay không. Nó thường được sử dụng cho các hoạt động dọn dẹp (đóng tệp, giải phóng tài nguyên).
Ví dụ:
try:
n = 0
res = 100 / n
except ZeroDivisionError:
print("You can't divide by zero!")
except ValueError:
print("Enter a valid number!")
else:
print("Result is", res)
finally:
print("Execution complete.")
Đầu ra:
You can't divide by zero!
Execution complete.
Giải thích:
Khối thử yêu cầu người dùng nhập dữ liệu và thử chia 100 cho số đã nhập.
ngoại trừ các khối xử lý ZeroDivisionError và ValueError.
Khối else chạy nếu không có ngoại lệ nào xảy ra, hiển thị kết quả.
khối cuối cùng chạy bất kể kết quả ra sao, cho biết việc thực hiện đã hoàn tất.
Ngoại lệ phổ biến trong Python
Python có nhiều ngoại lệ tích hợp , mỗi ngoại lệ đại diện cho một điều kiện lỗi cụ thể. Một số ngoại lệ phổ biến bao gồm:
Tên ngoại lệ | Mô tả |
---|---|
BaseException | Lớp cơ sở cho tất cả các ngoại lệ tích hợp sẵn. |
Exception | Lớp cơ sở cho tất cả các ngoại lệ không thoát. |
ArithmeticError | Lớp cơ sở cho tất cả các lỗi liên quan đến phép toán số học. |
ZeroDivisionError | Xảy ra khi thực hiện phép chia hoặc chia lấy dư với số chia là 0. |
OverflowError | Xảy ra khi một phép toán số vượt quá giới hạn của kiểu dữ liệu. |
FloatingPointError | Xảy ra khi thao tác với số thực (float) không thành công. |
AssertionError | Xảy ra khi câu lệnh assert không đúng. |
AttributeError | Xảy ra khi truy cập hoặc gán thuộc tính không tồn tại cho đối tượng. |
IndexError | Xảy ra khi chỉ số nằm ngoài phạm vi của chuỗi hoặc danh sách. |
KeyError | Xảy ra khi truy cập một khóa không tồn tại trong từ điển. |
MemoryError | Xảy ra khi chương trình hết bộ nhớ. |
NameError | Xảy ra khi sử dụng một biến chưa được định nghĩa. |
OSError | Xảy ra khi có lỗi liên quan đến hệ thống (như tệp hoặc I/O). |
TypeError | Xảy ra khi thực hiện thao tác trên kiểu dữ liệu không phù hợp. |
ValueError | Xảy ra khi một hàm nhận đúng kiểu dữ liệu nhưng giá trị không hợp lệ. |
ImportError | Xảy ra khi có vấn đề trong quá trình nhập mô-đun. |
ModuleNotFoundError | Xảy ra khi không tìm thấy mô-đun cần nhập. |
Python Bắt Ngoại Lệ
Khi làm việc với các ngoại lệ trong Python, chúng ta có thể xử lý lỗi hiệu quả hơn bằng cách chỉ định các loại ngoại lệ mà chúng ta mong đợi. Điều này có thể làm cho mã an toàn hơn và dễ gỡ lỗi hơn.
Bắt các ngoại lệ cụ thể
Việc phát hiện những ngoại lệ cụ thể giúp mã phản hồi với các loại ngoại lệ khác nhau theo cách khác nhau.
Ví dụ:
try:
x = int("str") # Điều này sẽ gây ra ValueError
#nghịch đảo
inv = 1 / x
except ValueError:
print("Not Valid!")
except ZeroDivisionError:
print("Zero has no inverse!")
Đầu ra:
Not Valid!
Giải thích:
Lỗi ValueError xảy ra vì chuỗi "str" không thể chuyển đổi thành số nguyên.
Nếu x bằng 0 và chuyển đổi thành công, ZeroDivisionError sẽ bị phát hiện khi cố gắng tính toán nghịch đảo của nó.
Bắt nhiều ngoại lệ
Chúng ta có thể bắt nhiều ngoại lệ trong một khối nếu chúng ta cần xử lý chúng theo cùng một cách hoặc chúng ta có thể tách chúng ra nếu các loại ngoại lệ khác nhau yêu cầu cách xử lý khác nhau.
Ví dụ:
a = ["10", "twenty", 30] # Danh sách hỗn hợp các số nguyên và chuỗi
try:
total = int(a[0]) + int(a[1]) # 'twenty' không thể chuyển đổi thành int
except (ValueError, TypeError) as e:
print("Error", e)
except IndexError:
print("Index out of range.")
Đầu ra:
Error invalid literal for int() with base 10: 'twenty'
Giải thích:
Lỗi ValueError xuất hiện khi cố gắng chuyển đổi "hai mươi" thành số nguyên.
TypeError có thể xảy ra nếu thao tác được áp dụng không đúng cho các kiểu không phải số nguyên, nhưng lỗi này không được kích hoạt trong thiết lập cụ thể này.
Lỗi IndexError sẽ được phát hiện nếu truy cập vào một chỉ mục nằm ngoài phạm vi của danh sách, nhưng trong trường hợp này, lỗi này nằm trong tầm kiểm soát.
Người xử lý Catch-All và rủi ro của họ
Sau đây là một phép tính đơn giản có thể sai vì nhiều lý do.
Ví dụ:
try:
# Mô phỏng tính toán rủi ro: thao tác kiểu không chính xác
res = "100" / 20
except ArithmeticError:
print("Arithmetic problem.")
except:
print("Something went wrong!")
Đầu ra:
Something went wrong!
Giải thích:
ArithmeticError (cụ thể hơn như ZeroDivisionError) có thể bị phát hiện nếu đây là lỗi chia số sang số. Tuy nhiên, TypeError thực sự được kích hoạt ở đây do cố gắng chia một chuỗi cho một số.
catch-all except: được sử dụng để bắt TypeError, chứng minh rủi ro là lập trình viên có thể không nhận ra nguyên nhân thực sự của lỗi (không khớp kiểu) nếu không ghi nhật ký lỗi chi tiết hơn.
Đưa ra một ngoại lệ
Chúng ta đưa ra một ngoại lệ trong Python bằng cách sử dụng từ khóa raise theo sau là một thể hiện của lớp ngoại lệ mà chúng ta muốn kích hoạt. Chúng ta có thể chọn từ các ngoại lệ tích hợp hoặc định nghĩa các ngoại lệ tùy chỉnh của riêng mình bằng cách kế thừa từ lớp Exception tích hợp của Python.
Cú pháp cơ bản:
raise ExceptionType("Thông báo lỗi")
Ví dụ:
def set(age):
if age < 0:
raise ValueError("Age cannot be negative.")
print(f"Age set to {age}")
try:
set(-5)
except ValueError as e:
print(e)
Đầu ra:
Age cannot be negative.
Giải thích:
Hàm set kiểm tra xem tuổi có phải là số âm không. Nếu có, nó sẽ đưa ra ValueError kèm theo thông báo giải thích vấn đề.
Điều này đảm bảo rằng thuộc tính tuổi không thể được đặt thành trạng thái không hợp lệ, do đó duy trì tính toàn vẹn của dữ liệu.
Ưu điểm của Xử lý ngoại lệ:
Cải thiện độ tin cậy của chương trình : Bằng cách xử lý các ngoại lệ đúng cách, bạn có thể ngăn chương trình bị sập hoặc tạo ra kết quả không chính xác do lỗi hoặc dữ liệu đầu vào không mong muốn.
Xử lý lỗi đơn giản : Xử lý ngoại lệ cho phép bạn tách mã xử lý lỗi khỏi logic chương trình chính, giúp việc đọc và bảo trì mã dễ dàng hơn.
Mã sạch hơn: Với việc xử lý ngoại lệ, bạn có thể tránh sử dụng các câu lệnh điều kiện phức tạp để kiểm tra lỗi, giúp mã sạch hơn và dễ đọc hơn.
Gỡ lỗi dễ dàng hơn : Khi có ngoại lệ xảy ra, trình thông dịch Python sẽ in ra một dấu vết cho thấy vị trí chính xác nơi ngoại lệ xảy ra, giúp bạn gỡ lỗi mã dễ dàng hơn.
Nhược điểm của Xử lý ngoại lệ:
Chi phí hiệu suất: Việc xử lý ngoại lệ có thể chậm hơn so với việc sử dụng các câu lệnh có điều kiện để kiểm tra lỗi, vì trình thông dịch phải thực hiện thêm công việc để phát hiện và xử lý ngoại lệ.
Tăng độ phức tạp của mã : Xử lý ngoại lệ có thể khiến mã của bạn phức tạp hơn, đặc biệt nếu bạn phải xử lý nhiều loại ngoại lệ hoặc triển khai logic xử lý lỗi phức tạp.
Rủi ro bảo mật có thể xảy ra: Các ngoại lệ được xử lý không đúng cách có khả năng tiết lộ thông tin nhạy cảm hoặc tạo ra lỗ hổng bảo mật trong mã của bạn, do đó, điều quan trọng là phải xử lý các ngoại lệ một cách cẩn thận và tránh tiết lộ quá nhiều thông tin về chương trình của bạn.
Published on Jun 20, 2025