INTRODUCTION
FLOW CONTROL
FUNCTIONS
DATATYPES
OBJECT & CLASS
Bài tập Python: Lập trình hướng đối tượng (OOP) trong Python Lập trình hướng đối tượng trong Python Class Variables trong Python Tìm hiểu về Methods trong Python Cách sử dụng phương thức __init__() trong Python Các biến Instance trong Python Tìm hiểu về Class Attributes trong Python Hàm Static Methods trong Python Phương thức __str__ trong Python Phương thức __repr__ trong Python Phương thức eq trong Python Tìm hiểu phương thức __hash__ trong Python Phương thức __bool__ trong Python Phương thức del trong Python Tìm hiểu về lớp Property trong Python Tìm hiểu về nạp chồng toán tử trong Python Trình Decorator Property trong Python Thuộc tính chỉ đọc trong Python Thuộc tính Delete trong Python Sử dụng super() trong Python Sử dụng __slots__ trong Python Cách sử dụng Protocol trong Python Sử dụng Enum aliases và @enum.unique trong Python Tùy chỉnh và mở rộng lớp Enum trong Python Cách sử dụng hàm Auto() của Python Single Responsibility Principle trong Python Nguyên tắc Đóng-Mở trong Python Nguyên tắc thay thế Liskov - LSP trong Python Interface Segregation Principle - ISP trong Python. Nguyên tắc đảo ngược sự phụ thuộc trong Python Đa kế thừa trong Python Tìm hiểu về các lớp mixin trong Python Mô tả Descriptors trong Python Phân biệt Data Descriptor và Non-data Descriptor trong Python Phương thức __new__ trong Python Tìm hiểu về Class Type trong Python Lớp Metaclass trong Python Ví dụ sử dụng metaclass trong Python Tìm hiểu về decorator dataclass trong Python Tìm hiểu về các ngoại lệ trong Python Ngoại lệ Raise trong Python Sử dụng câu lệnh raise from trong Python Ngoại lệ tùy chỉnh trong Python Module trong Python Package trong Python Class trong Python Hàm khởi tạo trong Python Kế thừa trong Python Đa kế thừa trong Python Setter và Getter trong Python Override trong Python Interface trong Python Bài tập Python: Module và Class
ADVANCED TOPICS
BỔ SUNG
PYTHON CĂN BẢN
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.

Tìm hiểu về các ngoại lệ trong Python

Trong quá trình lập trình, việc gặp phải các lỗi là điều không thể tránh khỏi. Những lỗi này, được gọi là ngoại lệ, có thể xảy ra do nhiều nguyên nhân khác nhau, từ việc nhập sai dữ liệu đến các vấn đề logic trong mã nguồn. Trong Python, việc xử lý các ngoại lệ không chỉ giúp cho chương trình của bạn chạy mượt mà hơn mà còn nâng cao trải nghiệm người dùng bằng cách cung cấp thông tin rõ ràng về những gì đã xảy ra. Bài viết này sẽ đưa bạn vào thế giới của các ngoại lệ trong Python, giải thích cách thức hoạt động của chúng và cách bạn có thể xử lý chúng một cách hiệu quả, đảm bảo chương trình của bạn không bị dừng lại một cách đột ngột khi gặp phải lỗi.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Giới thiệu về ngoại lệ trong Python

Trong Python, ngoại lệ là các đối tượng thuộc các lớp ngoại lệ. Tất cả các lớp ngoại lệ đều là các lớp con của lớp BaseException. Tuy nhiên, hầu hết các lớp ngoại lệ tích hợp đều kế thừa từ lớp Exception, là lớp con của lớp BaseException.

Screenshot 202024 10 08 20230433 png

Trang này cho thấy một cấu trúc lớp hoàn chỉnh cho các ngoại lệ tích hợp trong Python.

Ví dụ sau đây định nghĩa một danh sách có ba phần tử và cố gắng truy cập phần tử thứ tư:

colors = ['red', 'green', 'blue']
print(colors[3])

Chỉ số không hợp lệ đã gây ra ngoại lệ IndexError như mong đợi:

Bài viết này được đăng tại [free tuts .net]

IndexError: list index out of range

Khi một ngoại lệ xảy ra, Python sẽ dừng chương trình trừ khi bạn xử lý nó. Để xử lý ngoại lệ, bạn sử dụng câu lệnh try...except. Ví dụ:

colors = ['red', 'green', 'blue']

try:
    print(colors[3])
except IndexError as e:
    print(e)

print('Tiếp tục thực thi')

Kết quả:

<class 'IndexError'> - list index out of range
Tiếp tục thực thi

Trong ví dụ này, chúng ta đã sử dụng câu lệnh try...except để xử lý ngoại lệ IndexError. Như bạn thấy từ kết quả, chương trình tiếp tục thực thi sau câu lệnh try...except.

Phân cấp lớp ngoại lệ

Lớp IndexError kế thừa từ lớp LookupError, mà kế thừa từ lớp Exception. Bạn có thể bắt ngoại lệ từ lớp LookupError hoặc lớp Exception khi xảy ra ngoại lệ IndexError. Ví dụ:

colors = ['red', 'green', 'blue']

try:
    print(colors[3])
except LookupError as e:
    print(e.__class__, '-', e)

print('Tiếp tục thực thi')

Kết quả:

<class 'IndexError'> - list index out of range
Tiếp tục thực thi

Trong ví dụ này, ngoại lệ vẫn là IndexError mặc dù chúng ta bắt ngoại lệ từ lớp LookupError. Do đó, khi bạn xử lý một ngoại lệ, bộ xử lý ngoại lệ sẽ bắt loại ngoại lệ mà bạn chỉ định và bất kỳ lớp con nào của nó.

Chương trình sẽ hoạt động tương tự nếu bạn sử dụng lớp Exception thay vì lớp LookupError.

Screenshot 202024 10 08 20230447 png

Ví dụ về xử lý ngoại lệ trong Python

Ví dụ sau đây định nghĩa một hàm chia, trả về kết quả của a chia cho b:

def division(a, b):
    return a / b
c = division(10, 0)

Kết quả:

ZeroDivisionError: division by zero

Trong ví dụ này, nếu b bằng 0, ngoại lệ ZeroDivisionError sẽ xảy ra. Để xử lý ngoại lệ này, bạn sử dụng câu lệnh try...except như sau:

def division(a, b):
    try:
        return {
            'success': True,
            'message': 'OK',
            'result': a / b
        }
    except ZeroDivisionError as e:
        return {
            'success': False,
            'message': 'b không thể bằng 0',
            'result': None
        }

Kết quả của hàm sẽ là một từ điển có ba phần tử:

  • success: một giá trị boolean cho biết liệu thao tác có thành công hay không.
  • message: thông báo lỗi hoặc thông báo thành công.
  • result: lưu trữ kết quả của a chia cho b hoặc None nếu b bằng 0.

Kết quả nếu xảy ra ngoại lệ ZeroDivisionError:

{'success': False, 'message': 'b không thể bằng 0', 'result': None}

Bây giờ, nếu bạn không bắt ngoại lệ ZeroDivisionError mà chỉ bắt loại ngoại lệ tổng quát hơn như lớp Exception:

def division(a, b):
    try:
        return {
            'success': True,
            'message': 'OK',
            'result': a / b
        }
    except Exception as e:
        return {
            'success': False,
            'message': 'b không thể bằng 0',
            'result': None
        }

Kết quả sẽ vẫn như trước vì câu lệnh try...except cũng bắt được các ngoại lệ là lớp con của lớp Exception.

Tuy nhiên, nếu bạn truyền vào hai chuỗi thay vì hai số cho hàm division():

def division(a, b):
    try:
        return {
            'success': True,
            'message': 'OK',
            'result': a / b
        }
    except Exception as e:
        return {
            'success': False,
            'message': 'b không thể bằng 0',
            'result': None
        }

Kết quả:

{'success': False, 'message': 'b không thể bằng 0', 'result': None}

Trong ví dụ này, ngoại lệ không phải là ZeroDivisionError mà là TypeError. Tuy nhiên, mã vẫn xử lý nó như ngoại lệ ZeroDivisionError.

Vì vậy, bạn nên luôn xử lý các ngoại lệ từ cụ thể đến tổng quát. Ví dụ:

def division(a, b):
    try:
        return {
            'success': True,
            'message': 'OK',
            'result': a / b
        }
    except TypeError as e:
        return {
            'success': False,
            'message': 'Cả a và b phải là số',
            'result': None
        }
    except ZeroDivisionError as e:
        return {
            'success': False,
            'message': 'b không thể bằng 0',
            'result': None
        }
    except Exception as e:
        return {
            'success': False,
            'message': str(e),
            'result': None
        }

Trong ví dụ này, chúng ta đã bắt ngoại lệ TypeError, ZeroDivisionErrorException theo thứ tự xuất hiện trong câu lệnh try...except.

Nếu mã xử lý các ngoại lệ khác nhau là giống nhau, bạn có thể nhóm tất cả ngoại lệ thành một như sau:

def division(a, b):
    try:
        return {
            'success': True,
            'message': 'OK',
            'result': a / b
        }
    except (TypeError, ZeroDivisionError, Exception) as e:
        return {
            'success': False,
            'message': str(e),
            'result': None
        }

Kết quả:

{'success': False, 'message': 'division by zero', 'result': None}

Kết bài

Trong Python, ngoại lệ đóng vai trò quan trọng trong việc quản lý lỗi và duy trì sự ổn định của ứng dụng. Chúng là các đối tượng thuộc các lớp, mà hầu hết đều là các lớp con của lớp BaseException. Việc xử lý ngoại lệ từ cụ thể đến tổng quát không chỉ giúp chúng ta nhận diện và khắc phục các lỗi chính xác hơn mà còn mang lại khả năng kiểm soát tốt hơn đối với cách ứng dụng phản ứng trước những tình huống bất ngờ. Bằng cách áp dụng các kỹ thuật xử lý ngoại lệ một cách hợp lý, bạn có thể tạo ra những ứng dụng bền vững, thân thiện và dễ sử dụng hơn cho người dùng. Hãy nhớ rằng, một lập trình viên giỏi không chỉ biết viết mã mà còn biết cách xử lý các lỗi khi chúng phát sinh, từ đó cải thiện chất lượng mã nguồn và trải nghiệm người dùng.

Cùng chuyên mục:

Sử dụng câu lệnh raise from trong Python

Sử dụng câu lệnh raise from trong Python

Ngoại lệ tùy chỉnh trong Python

Ngoại lệ tùy chỉnh trong Python

Ngoại lệ Raise trong Python

Ngoại lệ Raise trong Python

Tìm hiểu về decorator dataclass trong Python

Tìm hiểu về decorator dataclass trong Python

Ví dụ sử dụng metaclass trong Python

Ví dụ sử dụng metaclass trong Python

Lớp Metaclass trong Python

Lớp Metaclass trong Python

Tìm hiểu về Class Type trong Python

Tìm hiểu về Class Type trong Python

Phương thức __new__ trong Python

Phương thức __new__ trong Python

Phân biệt Data Descriptor và Non-data Descriptor trong Python

Phân biệt Data Descriptor và Non-data Descriptor trong Python

Mô tả Descriptors trong Python

Mô tả Descriptors trong Python

Tìm hiểu về các lớp mixin trong Python

Tìm hiểu về các lớp mixin trong Python

Đa kế thừa trong Python

Đa kế thừa trong Python

Nguyên tắc đảo ngược sự phụ thuộc trong Python

Nguyên tắc đảo ngược sự phụ thuộc trong Python

Interface Segregation Principle - ISP trong Python.

Interface Segregation Principle - ISP trong Python.

Nguyên tắc thay thế Liskov - LSP trong Python

Nguyên tắc thay thế Liskov - LSP trong Python

Nguyên tắc Đóng-Mở trong Python

Nguyên tắc Đóng-Mở trong Python

Single Responsibility Principle trong Python

Single Responsibility Principle trong Python

Cách sử dụng hàm Auto() của Python

Cách sử dụng hàm Auto() của Python

Tùy chỉnh và mở rộng lớp Enum trong Python

Tùy chỉnh và mở rộng lớp Enum trong Python

Sử dụng Enum aliases và @enum.unique trong Python

Sử dụng Enum aliases và @enum.unique trong Python

Top