CodeGym /Khóa học Java /Python SELF VI /Tạo ngoại lệ của riêng bạn

Tạo ngoại lệ của riêng bạn

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

7.1 Tạo ngoại lệ tùy chỉnh

Thỉnh thoảng các ngoại lệ tiêu chuẩn trong Python không hoàn toàn đáp ứng nhu cầu của ứng dụng của bạn. Trong những trường hợp đó, bạn có thể tạo ngoại lệ của riêng mình bằng cách thừa kế chúng từ lớp cơ bản Exception hoặc bất kỳ lớp ngoại lệ thích hợp nào khác.

Các nguyên tắc cơ bản để tạo ngoại lệ tùy chỉnh

Việc tạo ngoại lệ tùy chỉnh bao gồm việc định nghĩa một lớp mới thừa kế từ lớp cơ bản Exception. Bạn có thể thêm các phương thức và thuộc tính của riêng mình vào lớp ngoại lệ của bạn để cung cấp thông tin chi tiết về lỗi.

Ví dụ tạo ngoại lệ tùy chỉnh đơn giản

Bước 1: Định nghĩa ngoại lệ tùy chỉnh


class MyCustomError(Exception):
    """Lớp dành cho ngoại lệ tùy chỉnh."""
    pass
        

Bước 2: Sử dụng ngoại lệ tùy chỉnh


def check_value(value):
    if value < 0:
        raise MyCustomError("Giá trị không được nhỏ hơn không")
            
try:
    check_value(-1)
except MyCustomError as e:
    print(f"Đã xảy ra ngoại lệ tùy chỉnh: {e}")
            

Rất đơn giản. Điều quan trọng là ngoại lệ của bạn được thừa kế từ lớp Exception hoặc một trong số các lớp con của nó.

7.2 Tạo ngoại lệ với các thuộc tính bổ sung

Bạn có thể thêm thuộc tính và phương thức vào lớp ngoại lệ của bạn để truyền tải thông tin bổ sung về lỗi đã xảy ra.

Ví dụ:


class NegativeValueError( Exception ):
    """Lớp dành cho ngoại lệ tùy chỉnh khi giá trị âm."""
    def __init__(self, value, message = "Giá trị không được nhỏ hơn không"):
        self.value = value
        self.message = message
        super().__init__(self.message)

    def __str__(self):
        return f'{self.message}: {self.value}'

Sử dụng ngoại lệ với các thuộc tính bổ sung


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)

try:
    check_value(-1)
except NegativeValueError as e:
    print(f"Đã xảy ra ngoại lệ tùy chỉnh: {e}")

Ngoại lệ của chúng ta là một lớp, được thừa kế từ lớp Exception. Do đó, bạn có thể làm tất cả những thứ mà bạn làm với bất kỳ lớp nào khác: thêm thuộc tính, phương thức, tham số khởi tạo, v.v.

Tất cả vì sự tiện lợi của bạn, và của những lập trình viên sẽ bắt ngoại lệ của bạn.

7.3 Tạo cấu trúc phân cấp cho ngoại lệ tùy chỉnh

Đối với những ứng dụng phức tạp hơn, việc tạo cấu trúc phân cấp ngoại lệ tùy chỉnh là hữu ích. Điều này cho phép nhóm các ngoại lệ có liên quan và đơn giản hóa cách xử lý chúng.

Ví dụ:


class ApplicationError(Exception):
    """Lớp cơ bản cho tất cả ngoại lệ của ứng dụng."""
    pass

class NegativeValueError(ApplicationError):
    """Lớp dành cho ngoại lệ tùy chỉnh khi giá trị âm."""
    def __init__(self, value, message="Giá trị không được nhỏ hơn không"):
        self.value = value
        self.message = message
        super().__init__(self.message)

    def __str__(self):
        return f'{self.message}: {self.value}'

class ValueTooLargeError(ApplicationError):
    """Lớp dành cho ngoại lệ tùy chỉnh khi giá trị quá lớn."""
    def __init__(self, value, message="Giá trị quá lớn"):
        self.value = value
        self.message = message
        super().__init__(self.message)

    def __str__(self):
        return f'{self.message}: {self.value}'

Sử dụng cấu trúc phân cấp ngoại lệ tùy chỉnh


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)

try:
    check_value(150)
except NegativeValueError as e:
    print(f"Đã xảy ra ngoại lệ: {e}")
except ValueTooLargeError as e:
    print(f"Đã xảy ra ngoại lệ: {e}")
except ApplicationError as e:
    print(f"Đã xảy ra ngoại lệ chung ứng dụng: {e}")

7.4 Thứ tự bắt ngoại lệ

Khi bắt ngoại lệ, đặc biệt là từ một cấu trúc phân cấp, điều quan trọng là phải chỉ định thứ tự đúng. Mặc dù mã trong các khối except không bao giờ được thực hiện đồng thời, nhưng điều quan trọng là lớp cơ bản của ngoại lệ có thể bắt tất cả các ngoại lệ của các lớp con của nó.

Ví dụ, mã sau:


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)
    
try:
    check_value(150)
except ApplicationError as e: # bắt các ngoại lệ thuộc loại ApplicationError và tất cả các con của nó
    print(f"Đã xảy ra ngoại lệ chung ứng dụng: {e}")

Trong khối except, sẽ bắt các ngoại lệ thuộc loại ApplicationError và tất cả các lớp con của nó.

Vì tất cả các ngoại lệ đều là lớp con của lớp Exception, do đó mã này sẽ bắt tất cả các ngoại lệ:


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)
    
try:
    check_value(150)
except Exception as e:
    print(f"Bắt tất cả các ngoại lệ: {e}")
except ApplicationError as e: # Mã này sẽ không bao giờ được thực hiện
    print(f"Đã xảy ra ngoại lệ chung ứng dụng: {e}")

Bắt ngoại lệ trong khối except ApplicationError sẽ không bao giờ xảy ra, vì khối except Exception bắt tất cả các ngoại lệ thuộc loại Exception và các lớp con của nó.

Giải pháp

Vì vậy, việc bắt ngoại lệ nên được thực hiện theo thứ tự ngược với thừa kế: càng gần lớp Exception, càng nằm dưới.

Ví dụ:


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)
        
try:
    check_value(150)
except NegativeValueError as e:
    print(f"Đã xảy ra ngoại lệ: {e}")
except ApplicationError as e:
    print(f"Đã xảy ra ngoại lệ chung ứng dụng: {e}")
except Exception as e:
    print(f"Bắt tất cả các ngoại lệ: {e}")

Trong ví dụ này, các khối except được đặt theo thứ tự phù hợp với cấu trúc phân cấp thừa kế của chúng: trước tiên bắt các ngoại lệ cụ thể hơn như NegativeValueError, sau đó mới đến các ngoại lệ chung hơn như ApplicationError. Điều này cho phép xử lý ngoại lệ một cách chính xác và tránh các tình huống khi một bộ xử lý chung hơn bắt một ngoại lệ trước khi các khối except chuyên biệt hơn có cơ hội xử lý nó.

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