Python - Ném Ngoại Lệ

Xin chào các bạn ơi, các bạn đam mê Python! Hôm nay, chúng ta sẽ bơi lội vào thế giới thú vị của việc ném ngoại lệ trong Python. Đừng lo nếu bạn mới bắt đầu học lập trình – tôi sẽ hướng dẫn bạn qua khái niệm này bước به bước, như thế tôi đã làm cho nhiều học viên khác trong những năm dạy học. Vậy hãy lấy ly cà phê yêu thích của bạn, và hãy cùng nhau bắt đầu cuộc phiêu lưu Python này!

Python - Raising Exceptions

Ném Ngoại Lệ trong Python

Hãy tưởng tượng bạn đang nấu một bữa ăn ngon miệng, nhưng đột ngột bạn nhận ra mình hết nguyên liệu quan trọng. Bạn sẽ làm gì? Bạn có thể sẽ dừng nấu nướng và cảnh báo mọi người về vấn đề này, phải không? Đúng vậy, điều đó chính là việc ném ngoại lệ trong Python – đó là cách để thông báo rằng có một điều bất ngờ hoặc gây vấn đề đã xảy ra trong mã của bạn.

Tại Sao Ném Ngoại Lệ?

Việc ném ngoại lệ cho phép chúng ta:

  1. Chỉ ra lỗi hoặc tình huống bất thường
  2. Kiểm soát luồng của chương trình
  3. Cung cấp phản hồi có ý nghĩa cho người dùng hoặc các phần khác của mã của chúng ta

Hãy bắt đầu với một ví dụ đơn giản:

def chia(a, b):
if b == 0:
raise ValueError("Không thể chia cho zero!")
return a / b

try:
ket_qua = chia(10, 0)
except ValueError as e:
print(f"Oops! Có lỗi xảy ra: {e}")

Trong ví dụ này, chúng ta đang ném một ValueError khi ai đó cố gắng chia cho không. Hãy phân tích nó:

  1. Chúng ta định nghĩa một hàm chia(a, b) kiểm tra nếu b là không.
  2. Nếu b là không, chúng ta ném một ValueError với thông điệp tùy chỉnh.
  3. Chúng ta sử dụng một khối try-except để chặt ngoại lệ và in ra một thông điệp thân thiện.

Khi bạn chạy mã này, bạn sẽ thấy:

Oops! Có lỗi xảy ra: Không thể chia cho zero!

Ném Ngoại Lệ Định Sẵn

Python đi kèm với nhiều loại ngoại lệ định sẵn mà chúng ta có thể ném. Dưới đây là bảng một số ngoại lệ phổ biến:

Ngoại Lệ Mô Tả
ValueError Ném khi một hàm nhận được đối số của loại đúng nhưng giá trị không phù hợp
TypeError Ném khi một thao tác hoặc hàm được áp dụng vào một đối tượng của loại không phù hợp
IndexError Ném khi chỉ số chuỗi nằm ngoài phạm vi
KeyError Ném khi không tìm thấy khóa trong từ điển
FileNotFoundError Ném khi yêu cầu một tệp hoặc thư mục nhưng không tồn tại

Hãy xem một số ví dụ:

def kiem_tra_tuoi(tuoi):
if not isinstance(tuoi, int):
raise TypeError("Tuổi phải là một số nguyên")
if tuoi < 0:
raise ValueError("Tuổi không thể âm")
print(f"Tuổi của bạn là {tuoi}")

try:
kiem_tra_tuoi("hai mươi")
except TypeError as e:
print(f"Lỗi kiểu: {e}")

try:
kiem_tra_tuoi(-5)
except ValueError as e:
print(f"Lỗi giá trị: {e}")

Khi bạn chạy mã này, bạn sẽ thấy:

Lỗi kiểu: Tuổi phải là một số nguyên
Lỗi giá trị: Tuổi không thể âm

Ném Ngoại Lệ Tùy Chỉnh

Thỉnh thoảng, các ngoại lệ định sẵn không đủ. Đó là khi chúng ta tạo ra các ngoại lệ tùy chỉnh của riêng mình! Nó như là một đầu bếp tạo ra các công thức độc đáo của riêng mình.

Tạo Ngoại Lệ Tùy Chỉnh

Để tạo một ngoại lệ tùy chỉnh, chúng ta chỉ cần định nghĩa một lớp mới kế thừa từ lớp Exception:

class QuaSoLuongPizzaError(Exception):
pass

def dat_pizza(so_luong):
if so_luong > 100:
raise QuaSoLuongPizzaError("Ngáo! Đó quá nhiều pizza để xử lý!")
print(f"Đặt hàng thành công: {so_luong} pizza")

try:
dat_pizza(101)
except QuaSoLuongPizzaError as e:
print(f"Đặt hàng thất bại: {e}")

Trong ví dụ ngon miệng này:

  1. Chúng ta định nghĩa một ngoại lệ tùy chỉnh QuaSoLuongPizzaError.
  2. Hàm dat_pizza của chúng ta ném ngoại lệ này nếu ai đó đặt nhiều hơn 100 pizza.
  3. Chúng ta chặt ngoại lệ và in ra một thông điệp thân thiện.

Khi bạn chạy mã này, bạn sẽ thấy:

Đặt hàng thất bại: Ngáo! Đó quá nhiều pizza để xử lý!

Ném Lại Ngoại Lệ

Thỉnh thoảng, bạn có thể muốn chặt một ngoại lệ, làm điều gì đó với nó, và sau đó ném lại để ai đó khác xử lý. Nó giống như trao bóng đỏ trong một trò chơi!

Dưới đây là cách bạn có thể làm điều đó:

def thuc_hien_hang_rong():
print("Bắt đầu thực hiện hoạt động nguy hiểm...")
raise ValueError("Có điều gì đó không đúng!")

def thuc_hien_hoat_dong():
try:
thuc_hien_hang_rong()
except ValueError:
print("Chặt được lỗi, ghi lại nó...")
raise  # Ném lại ngoại lệ

try:
thuc_hien_hoat_dong()
except ValueError as e:
print(f"Thực hiện thất bại: {e}")

Trong ví dụ này:

  1. thuc_hien_hang_rong() luôn ném một ValueError.
  2. thuc_hien_hoat_dong() chặt ngoại lệ, ghi lại nó, và sau đó ném lại.
  3. Chúng ta chặt ngoại lệ được ném lại trong khối try-except ngoài.

Khi bạn chạy mã này, bạn sẽ thấy:

Bắt đầu thực hiện hoạt động nguy hiểm...
Chặt được lỗi, ghi lại nó...
Thực hiện thất bại: Có điều gì đó không đúng!

Và thế là, các bạn ơi! Chúng ta đã bao gồm việc ném ngoại lệ, ngoại lệ định sẵn, ngoại lệ tùy chỉnh, và thậm chí còn ném lại ngoại lệ. Hãy nhớ, ngoại lệ không phải là kẻ thù của bạn – chúng là các công cụ có giá trị giúp bạn viết mã mạnh mẽ và chống lỗi.

Như tôi luôn nói với các học viên, việc lập trình như học lái xe đạp. Bạn có thể ngã một số lần, nhưng mỗi lần ngã (hoặc ngoại lệ) đều dạy bạn điều mới. Hãy tiếp tục tập luyện, duy trì sự tò mò, và đừng sợ ném một số ngoại lệ trong hành trình!

Chúc mãi mãi vui vẻ, và may các ngoại lệ của bạn luôn có ý nghĩa! ?✨

Credits: Image by storyset