CodeGym /Các khóa học /Python SELF VI /Xử lý ngoại lệ

Xử lý ngoại lệ

Python SELF VI
Mức độ , Bài học
Có sẵn

3.1 Bắt ngoại lệ

Chúng ta sẽ không nói nhiều về ngoại lệ nếu chúng ta chỉ cần quan sát chúng. Ngoại lệ là những đối tượng đặc biệt mà chương trình Python của bạn có thể làm việc cùng. Xử lý ngoại lệ là một khía cạnh quan trọng của lập trình, cho phép cải thiện độ tin cậy và khả năng chịu lỗi của chương trình.

Trong Python, để bắt và xử lý ngoại lệ người ta sử dụng các cấu trúc try, except, else, và finally. Những cấu trúc này cho phép bắt các lỗi xảy ra trong quá trình chạy chương trình và thực hiện các hành động tương ứng.

Cấu trúc try-except

Cấu trúc try-except được dùng để bắt và xử lý ngoại lệ. Khối try chứa mã có thể gây ra ngoại lệ, và khối except chứa mã sẽ được thực thi nếu có ngoại lệ xảy ra.

Ví dụ:


try:
    result = 10 / 0
except ZeroDivisionError:
    print("Lỗi: chia cho không.")

Nếu mã bên trong khối try phát sinh ngoại lệ ZeroDivisionError, nó sẽ bị bắt bởi khối except và mã với lệnh gọi print() sẽ được thực thi.

Xử lý nhiều ngoại lệ

Bạn có thể xử lý nhiều loại ngoại lệ bằng cách chỉ định chúng trong các khối except riêng biệt.


try:
    result = int("abc")
except ZeroDivisionError:
    print("Lỗi: chia cho không.")
except ValueError:
    print("Lỗi: giá trị không hợp lệ.")

Bắt tất cả ngoại lệ

Nếu bạn muốn bắt tất cả ngoại lệ, bạn có thể sử dụng khối except mà không chỉ định loại ngoại lệ cụ thể. Tuy nhiên, điều này không được khuyến khích, vì nó có thể gây khó khăn trong việc gỡ lỗi và che giấu các lỗi quan trọng.


try:
    result = 10 / 0
except:
    print("Đã xảy ra lỗi.")

3.2 Toán tử elsefinally

Ngoài các toán tử tryexcept, còn có hai tùy chọn: elsefinally. Bây giờ, mình sẽ nói rõ hơn về chúng.

Cấu trúc try-except-else

Khối else được dùng để thực thi mã, nếu khối try không phát sinh ngoại lệ.


try:
    result = 10 / 2
except ZeroDivisionError:
    print("Lỗi: chia cho không.")
else:
    print(f"Kết quả: {result}")

Cấu trúc try-except-finally

Khối finally chứa mã sẽ được thực thi bất kể ngoại lệ có xảy ra hay không. Điều này rất hữu ích để giải phóng tài nguyên hoặc thực hiện các thao tác kết thúc.


try:
    result = 10 / 0
except ZeroDivisionError:
    print("Lỗi: chia cho không.")
finally:
    print("Khối này luôn được thực thi.")

Ví dụ đầy đủ: try-except-else-finally

Ví dụ:


try:
    result = 10 / 2
except ZeroDivisionError:
    print("Lỗi: chia cho không.")
else:
    print(f"Kết quả: {result}")
finally:
    print("Khối này luôn được thực thi.")

3.3 Ví dụ try-except-else-finally

Hãy xét một ví dụ thực tế lớn. Chẳng hạn, chúng ta đang cố đọc dữ liệu từ một file trên ổ đĩa — điều này có vẻ đơn giản phải không?


file = open("file.txt", "r")
content = file.read()
print(content)

Có thể xảy ra những gì không định trước? Ví dụ như, tất cả:

  • File có thể không tồn tại. Nó có thể bị xóa tình cờ, không được ghi, hoặc chương trình của bạn thực sự đang chạy trên một máy tính khác, nơi nó chưa bao giờ tồn tại.
  • Lỗi đọc file. Chương trình của bạn không thể truy cập được, vì nó nằm trong thư mục mà cần quyền admin.
  • Chương trình khác hiện đang ghi vào file này và nó không thể đọc được — chương trình đó có quyền truy cập độc quyền vào file.

Bạn thấy sao? Vậy hãy nhớ rằng, bất kể lỗi xảy ra ở bước nào khi làm việc với file, bạn nhất định phải "đóng" file, để hệ điều hành giải phóng tài nguyên đã được cấp phát cho việc làm việc với file đó.

Vậy nên mã thực tế sẽ trông như thế này:


try:
    file = open("non_existent_file.txt", "r")
    content = file.read()
except FileNotFoundError:
    print("Lỗi: không tìm thấy file.")
except IOError:
    print("Lỗi: lỗi nhập-xuất.")
else:
    print(content)
finally:
    if 'file' in locals() and not file.closed:
        file.close()
        print("File đã đóng.")

Chào mừng bạn đến với thế giới thực, nơi bạn cần phải viết mã không chỉ cho "kịch bản hoạt động", mà còn cho tất cả các kịch bản có thể xảy ra sự cố.

Thôi, mình không định làm bạn sợ — điều này dễ hơn bạn nghĩ. Bạn chỉ cần hiểu các điều kiện biên (corner cases) và thêm kiểm tra các lỗi tiêu chuẩn đúng lúc. Phần còn lại các framework hiện đại sẽ lo cho bạn.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION