Ngoại lệ (Exceptions) có thể được ném ra bởi trình thông dịch Python và thủ công. Các ngoại lệ tích hợp sẵn giúp bắt các lỗi phổ biến trong chương trình.
Trong hướng dẫn này, chúng ta thảo luận ngoại lệ là gì và cách chúng được sử dụng. Chúng ta sẽ đi qua ví dụ cách ném ngoại lệ để bạn làm việc với chúng trong mã.
Ngoại lệ (Exception) là gì?
Ngoại lệ, còn gọi là lỗi logic (logical error), là lỗi xảy ra trong thời gian chạy chương trình (runtime).
Có hai loại lỗi trong Python: lỗi cú pháp (syntax errors) và lỗi runtime. Lỗi cú pháp được ném ra trước khi chương trình chạy. Nếu chương trình gặp lỗi cú pháp, nó không thể chạy. Điều này là do Python không thể thông dịch mã chứa lỗi cú pháp.
Lỗi runtime, còn gọi là ngoại lệ, được gặp khi Python chạy chương trình. Ngoại lệ có thể được ném ra ở dòng 30. Nếu ngoại lệ ném ra ở dòng 30, 30 dòng mã sẽ chạy, rồi chương trình dừng.
Ví dụ ngoại lệ:
Traceback (most recent call last): File "main.py", line 6, ins_names.append(n) AttributeError: 'str' object has no attribute 'append'
Ngoại lệ này báo Python không thể chạy phần còn lại của mã. Nếu gặp ngoại lệ, hãy đọc kỹ thông báo. Thông báo lỗi sẽ nói cho bạn hầu hết, nếu không phải tất cả, những gì cần để khắc phục.
Phân tích câu cuối trong thông báo lỗi:
AttributeError: 'str' object has no attribute 'append'
Trong trường hợp này, lỗi là AttributeError. Nghĩa là chúng ta tham chiếu thuộc tính không tồn tại. Thông báo báo chúng ta dùng append() trên đối tượng chuỗi, điều không được phép.
Vì đối tượng chuỗi không hỗ trợ append(), bước tiếp theo tốt là tìm tương đương append() cho chuỗi. Đó là nối (concatenation). Bây giờ chúng ta có giải pháp tiềm năng cho vấn đề lập trình.
Nơi có thể gặp ngoại lệ?
Để giúp lập trình viên bắt lỗi, Python có nhiều ngoại lệ tích hợp. Chúng giúp xác định nguyên nhân vấn đề để khắc phục. Dưới đây là một vài ngoại lệ phổ biến:
TypeError: Xảy ra khi áp dụng hàm cho đối tượng kiểu không hỗ trợ hàm đó. (ví dụ: TypeError: can only join an iterable)SyntaxError: Ném ra trước chương trình thực thi báo vấn đề cú pháp (ví dụ: SyntaxError: invalid syntax)KeyError: Xảy ra nếu tham chiếu khóa trong từ điển không tồn tại. (ví dụ: KeyError: "usb_ports")ImportError: Xảy ra nếu import gói không tồn tại, hoặc hàm từ gói không tồn tại.
Chúng ta chỉ liệt kê một vài trong nhiều ngoại lệ bạn có thể gặp trong Python.
Cách ném ngoại lệ (Raise an Exception)
Bạn có thể định nghĩa ngoại lệ tùy chỉnh trong mã. Điều này hữu ích nếu ngoại lệ tích hợp Python không phù hợp nhu cầu chương trình.
Chúng ta viết chương trình xác thực mật khẩu cho game. Đầu tiên, yêu cầu người dùng nhập mật khẩu:
password = input("Enter a password: ")
Để mật khẩu hợp lệ, phải dài hơn 12 ký tự. Nếu mật khẩu 12 ký tự hoặc ít hơn, chúng ta muốn ném ngoại lệ.
Để làm điều này, dùng câu lệnh if. Câu lệnh if sau kiểm tra mật khẩu người dùng chọn có ít hơn 12 ký tự:
if len(password) > 12:
print("Your password is valid.")
else:
raise Exception("Your password is not the correct length.")
Chúng ta dùng len() tính độ dài mật khẩu. Nếu người dùng nhập mật khẩu không hợp lệ, chương trình ném ngoại lệ với thông báo "Your password is not the correct length."
Thử mã:
Enter a password: Bacon120 Traceback (most recent call last): File "main.py", line 6, inraise Exception("Your password is not the correct length.") Exception: Your password is not the correct length.
Mật khẩu nhập dưới 12 ký tự. Mã dừng vì nhập mật khẩu không hợp lệ. Thử chạy với mật khẩu hợp lệ:
Enter a password: Bacon120Bacon120 Your password is valid.
Chương trình thực thi thành công.
Cách xử lý ngoại lệ (Handle an Exception)
Mặc định, ngoại lệ dừng thực thi chương trình. Mặc dù hữu ích vì nó buộc bạn tìm giải pháp, có trường hợp bạn không muốn chương trình dừng nếu ngoại lệ ném ra.
Ví dụ, nếu kiểm tra điểm dữ liệu trong danh sách có hợp lệ, bạn có thể không muốn ngoại lệ ném ra mỗi khi phát hiện điểm không hợp lệ.
Để xử lý ngoại lệ, dùng khối try...except. Viết chương trình tìm mục trong từ điển. Từ điển chứa tên học sinh và điểm bài kiểm tra gần nhất.
Đầu tiên, định nghĩa từ điển thông tin học sinh và điểm:
data = {
"Lucy": 73,
"Carlton": 59,
"Adam": 73
}
Tiếp theo, yêu cầu người dùng nhập tên học sinh muốn truy xuất điểm. Chúng ta làm trong khối "try" để xử lý ngoại lệ sau:
try:
student = input("Enter the name of the student whose grade you want to retrieve: ")
print(data[student])
Mã in điểm học sinh tên khớp với tên người dùng nhập. Tuy nhiên, nếu người dùng nhập tên không hợp lệ, KeyError sẽ xảy ra.
Chúng ta xử lý bằng thêm khối except:
try:
student = input("Enter the name of the student whose grade you want to retrieve: ")
print(data[student])
except:
print("This student is not present in the list of grades.")
Nếu không tìm thấy học sinh, mệnh đề except chạy. Chạy chương trình:
Enter the name of the student whose grade you want to retrieve: Lucy 73
Khi nhập tên hợp lệ, chương trình hoạt động. Thử với tên không hợp lệ:
Enter the name of the student whose grade you want to retrieve: Kaitlin This student is not present in the list of grades.
Ngoại lệ được ném ra nhưng chương trình không dừng. Thay vào đó, nội dung khối "except" được thực thi.
Để tìm hiểu thêm về try...except, đọc hướng dẫn Python try...except.
Kết luận
Ngoại lệ báo cho bạn biết có lỗi logic trong mã. Khi ngoại lệ ném ra, bạn thấy loại ngoại lệ, vị trí ném, và thông báo lỗi. Bạn dùng thông tin này tìm nguyên nhân.
Bạn có thể ném ngoại lệ riêng dùng câu lệnh raise. Bạn có thể xử lý ngoại lệ dùng khối try...except.
Bây giờ bạn đã có công cụ khắc phục ngoại lệ Python như pro!