Trong Python, ngoại lệ Exception là một sự kiện được kích hoạt khi xảy ra lỗi trong quá trình thực thi chương trình. Khi Python script gặp một tình huống mà nó không thể xác định trước, nó sẽ tạo ra một exception. Exception có thể được xử lý bằng cách sử dụng các câu lệnh try
và except
, giúp chương trình của bạn tiếp tục chạy mà không bị gián đoạn bởi lỗi.
Mục tiêu bài học
- Biết Exception là gì? mục đích của nó
- Chạy thử exception
- Tự viết 1 exception
- Biết qua 1 số exception mặc định có trong Python
Try - Except trong Python
Ví dụ về Exception
try:
# Mã có thể phát sinh exception
result = 10 / 0
except ZeroDivisionError:
# Xử lý exception cụ thể
print("Không thể chia cho 0.")
except Exception as e:
# Xử lý bất kỳ exception nào khác
print(f"Đã xảy ra lỗi: {e}")
else:
# Mã này sẽ chạy nếu không có exception nào được ném ra
print("Phép chia thành công.")
finally:
# Mã này sẽ chạy dù có exception hay không
print("Đây là khối finally.")
Trong ví dụ trên, nếu phép chia cho 0 được thực hiện, một ZeroDivisionError
sẽ được ném ra và xử lý trong khối except
tương ứng. Nếu có một loại lỗi khác, nó sẽ tiếp tục được bắt và xử lý bởi except Exception as e
.
Python cung cấp nhiều loại built-in exceptions như IndexError
, KeyError
, ValueError
, TypeError
, v.v., cho phép bạn xử lý nhiều tình huống lỗi khác nhau. Bạn cũng có thể tạo ra các exception tùy chỉnh của riêng mình bằng cách kế thừa từ lớp Exception
.
Cuối cùng trong ví dụ là lớp finally, dù trong Try Exception có xảy ra lỗi hay không thì chương trình luôn luôn chạy vào finally.
Vậy luồng chạy của Exception như sau:
- Xử lý code trong Try
- Nếu không lỗi -> chạy vào Finally
- Nếu có lỗi -> chạy vào exception tương ứng, nếu không có exception tương ứng, chương trình sẽ chạy vào Exception chung -> sau đó chạy vào Finally.
Tại sao cần Exception
Không chỉ trong Python, mà bất kỳ ngôn ngữ lập trình nào cũng cần có Exception, cơ chế này giúp xử lý lỗi linh hoạt, an toàn:
-
Kiểm soát luồng chương trình: Exception cho phép bạn kiểm soát luồng chương trình khi xảy ra lỗi. Thay vì chương trình bị kết thúc ngay lập tức và trả về mã lỗi khó hiểu, bạn có thể chuyển luồng thực thi đến một phần khác của chương trình để xử lý lỗi.
-
Phân biệt các loại lỗi: Có nhiều loại lỗi khác nhau có thể xảy ra, và exception giúp bạn phân biệt chúng thông qua việc sử dụng các loại exception khác nhau.
-
Code sạch và dễ đọc: Việc xử lý exception giúp mã code của bạn trở nên sạch sẽ và dễ đọc hơn. Bạn có thể tập trung vào logic chính của chương trình mà không phải lo lắng về việc xử lý lỗi ở mọi nơi.
-
Phát triển và bảo trì: Khi phát triển phần mềm, việc xử lý exception giúp bạn dễ dàng tìm và sửa lỗi hơn. Nó cũng giúp việc bảo trì mã trở nên dễ dàng hơn khi chương trình đã được triển khai.
-
Thông báo lỗi rõ ràng: Exception cung cấp một cách để thông báo lỗi một cách rõ ràng và chi tiết, giúp người dùng hoặc nhà phát triển hiểu được vấn đề và cách khắc phục.
-
An toàn: Trong một số trường hợp, việc xử lý lỗi không đúng cách có thể dẫn đến hậu quả nghiêm trọng, như mất mát dữ liệu. Exception giúp đảm bảo rằng lỗi được xử lý một cách an toàn.
-
Tái sử dụng mã: Exception giúp bạn tạo ra các hàm và module có thể tái sử dụng mà không cần phải viết lại cách xử lý lỗi cho mỗi trường hợp sử dụng.
Tự viết 1 Exception trong Python
Ngoài các Exception Python cung cấp sẵn, bạn có thể viết của riêng mình phục vụ logic nào đó, phần này chỉ mang tính giới thiệu, bạn hãy copy code và chạy nhé, khi học tới các bài nâng cao bạn sẽ hiểu hơn về nó.
Ví dụ viết một Exception tùy chỉnh, gặp số có giá trị nhỏ hơn 10 sẽ báo lỗi.
class ErrorTooSmall(Exception):
"""Exception được ném ra khi giá trị nhập vào quá nhỏ."""
def __init__(self, message="Giá trị quá nhỏ"):
self.message = message
super().__init__(self.message)
# sử dụng exception tùy chỉnh
try:
value = int(input("Nhập một số lớn hơn 10: "))
if value < 10:
raise ErrorTooSmall
except ErrorTooSmall as e:
print(e)
else:
print("Giá trị hợp lệ!")
Một số Exeption mặc định trong Python
Dưới đây là danh sách một số exception mặc định trong Python, bạn có thể tham khảo, không cần phải thuộc, nhưng biết sự tồn tại của chúng sẽ giúp ích khi lập trình trong tương lai:
Exception | Mô tả |
---|---|
BaseException |
Lớp cơ sở cho tất cả exceptions |
SystemExit |
Ném ra bởi hàm sys.exit() |
KeyboardInterrupt |
Ném ra khi người dùng nhấn vào phím ngắt (ví dụ: Ctrl+C) |
GeneratorExit |
Ném ra khi một generator hoặc coroutine được đóng |
Exception |
Lớp cơ sở thông thường cho tất cả exceptions không phải là lỗi hệ thống |
StopIteration |
Ném ra bởi next() để báo hiệu không còn giá trị nào để lấy từ iterator |
StopAsyncIteration |
Ném ra bởi next() trong một async iterator để báo hiệu không còn giá trị nào để lấy |
ArithmeticError |
Lớp cơ sở cho các lỗi xảy ra trong các phép toán số học |
FloatingPointError |
Ném ra khi một phép toán số học dấu phẩy động thất bại |
OverflowError |
Ném ra khi kết quả của một phép toán số học vượt quá giới hạn biểu diễn |
ZeroDivisionError |
Ném ra khi phép chia hoặc phép chia modulo cho số 0 |
AssertionError |
Ném ra khi một câu lệnh assert thất bại |
AttributeError |
Ném ra khi tham chiếu hoặc gán thuộc tính thất bại |
BufferError |
Ném ra khi có thao tác liên quan đến buffer không thể thực hiện được |
EOFError |
Ném ra khi hàm input() đạt đến điều kiện “end of file” (EOF) mà không đọc được dữ liệu nào |
ImportError |
Ném ra khi một lệnh import thất bại |
ModuleNotFoundError |
Một subclass của ImportError , ném ra khi không tìm thấy module |
LookupError |
Lớp cơ sở cho các exceptions khi một phép tra cứu key hoặc index thất bại |
IndexError |
Ném ra khi index không nằm trong phạm vi của sequence |
KeyError |
Ném ra khi một key không tồn tại trong dictionary |
MemoryError |
Ném ra khi một thao tác không thể hoàn thành do thiếu bộ nhớ |
NameError |
Ném ra khi một tên local hoặc global không được tìm thấy |
UnboundLocalError |
Một subclass của NameError , ném ra khi một biến local được tham chiếu mà không được gán trước đó |
OSError |
Ném ra khi một hàm hệ thống trả về một lỗi liên quan đến hệ thống |
BlockingIOError |
Một subclass của OSError , ném ra khi một hoạt động I/O bị chặn |
ChildProcessError |
Một subclass của OSError , ném ra khi có vấn đề liên quan đến quá trình con |
ConnectionError |
Một subclass của OSError , ném ra cho các lỗi liên quan đến kết nối mạng |
FileExistsError |
Một subclass của OSError , ném ra khi cố gắng tạo một file hoặc directory đã tồn tại |
FileNotFoundError |
Một subclass của OSError , ném ra khi một file hoặc directory được yêu cầu không tồn tại |
InterruptedError |
Một subclass của OSError , ném ra khi một hàm hệ thống bị gián đoạn bởi một tín hiệu đến |
IsADirectoryError |
Một subclass của OSError , ném ra khi một thao tác file yêu cầu một file nhưng đó là một directory |
NotADirectoryError |
Một subclass của OSError , ném ra khi một thao tác directory yêu cầu một directory nhưng đó là một file |
PermissionError |
Một subclass của OSError , ném ra khi cố gắng thực hiện một thao tác mà không có quyền truy cập đủ |
ProcessLookupError |
Một subclass của OSError , ném ra khi một quá trình được yêu cầu không tồn tại |
TimeoutError |
Một subclass của OSError , ném ra khi một hoạt động chờ đợi vượt quá thời gian đã định |
ReferenceError |
Ném ra khi một weak reference proxy được sử dụng để truy cập một thuộc tính của đối tượng đã bị garbage collected |
RuntimeError |
Ném ra khi một lỗi không thuộc về bất kỳ category nào khác |
NotImplementedError |
Ném ra khi một phương thức trừu tượng cần được subclass override nhưng lại không được |
RecursionError |
Một subclass của RuntimeError , ném ra khi độ sâu đệ quy vượt quá giới hạn Python |
SyntaxError |
Ném ra khi có lỗi cú pháp trong mã Python |
IndentationError |
Một subclass của SyntaxError , ném ra khi có lỗi thụt lề |
TabError |
Một subclass của IndentationError , ném ra khi thụt lề không đồng nhất giữa tabs và spaces |
SystemError |
Ném ra khi trình thông dịch gặp một vấn đề nội bộ, nhưng khi mã Python không thể xử lý được |
TypeError |
Ném ra khi một thao tác hoặc hàm được áp dụng cho một đối tượng của kiểu không phù hợp |
ValueError |
Ném ra khi một thao tác hoặc hàm nhận một đối số có kiểu đúng nhưng giá trị không phù hợp |
UnicodeError |
Ném ra khi có lỗi liên quan đến mã hóa hoặc giải mã unicode |
UnicodeEncodeError |
Một subclass của UnicodeError , ném ra khi có lỗi mã hóa unicode |
UnicodeDecodeError |
Một subclass của UnicodeError , ném ra khi có lỗi giải mã unicode |
UnicodeTranslateError |
Một subclass của UnicodeError , ném ra khi có lỗi dịch unicode |