CodeGym /Adesua ahorow /Python SELF TW /創建自定義例外

創建自定義例外

Python SELF TW
等級 18 , 課堂 1
開放

7.1 創建自定義例外

有時候,Python 的預設例外無法完全滿足你應用程序的需求。在這種情況下,你可以通過繼承基類 Exception 或其他合適的例外類來創建自己的例外。

創建自定義例外的基礎

創建自定義例外包括定義一個新的類,這個類繼承自基類 Exception。你可以在例外類中添加自己的方法和屬性,以提供更多的錯誤信息。

簡單自定義例外的示例

步驟1:定義自定義例外


class MyCustomError(Exception):
    """自定義例外的類。"""
    pass
        

步驟2:使用自定義例外


def check_value(value):
    if value < 0:
        raise MyCustomError("值不應該小於零")
            
try:
    check_value(-1)
except MyCustomError as e:
    print(f"發生了自定義例外: {e}")
            

這非常簡單。關鍵是你的例外需要繼承自 Exception 類或它的子類。

7.2 創建帶有附加屬性的例外

你可以在你的例外類中添加屬性和方法,以傳遞更多有關錯誤的信息。

示例:


class NegativeValueError( Exception ):
    """當值為負時,自定義例外的類。"""
    def __init__(self, value, message = "值不應該小於零"):
        self.value = value
        self.message = message
        super().__init__(self.message)

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

使用帶有附加屬性的例外


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

try:
    check_value(-1)
except NegativeValueError as e:
    print(f"發生了自定義例外: {e}")

我們的例外是從 Exception 類繼承的類。因此,您可以像對任何其他類一樣對它進行操作:添加字段、方法、構造函數參數等。

這一切都是為了您的方便,以及將要處理您的例外的程序員的方便。

7.3 創建自定義例外的層次結構

對於更複雜的應用程序,創建自定義例外的層次結構是有用的。它允許你將相關的例外分組,並簡化它們的處理。

示例:


class ApplicationError(Exception):
    """應用程序所有例外的基礎類。"""
    pass

class NegativeValueError(ApplicationError):
    """當值為負時,自定義例外的類。"""
    def __init__(self, value, message="值不應該小於零"):
        self.value = value
        self.message = message
        super().__init__(self.message)

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

class ValueTooLargeError(ApplicationError):
    """當值太大時,自定義例外的類。"""
    def __init__(self, value, message="值太大"):
        self.value = value
        self.message = message
        super().__init__(self.message)

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

使用自定義例外的層次結構


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"發生了例外: {e}")
except ValueTooLargeError as e:
    print(f"發生了例外: {e}")
except ApplicationError as e:
    print(f"應用程序通用例外: {e}")

7.4 捕獲例外的順序

捕獲例外時,尤其是同一層次結構中的例外時,指定它們的正確順序很重要。雖然 except 塊中的代碼不會同時執行,但事實是基礎例外類能夠捕捉所有子類的例外

例如,代碼:


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)
    
try:
    check_value(150)
except ApplicationError as e: # 捕捉類型為 ApplicationError 及其所有子類的例外
    print(f"應用程序通用例外: {e}")

except 塊中,將捕捉類型為 ApplicationError 及其所有子類的例外。

由於所有的例外都是從 Exception 類繼承的,所以這樣的代碼將捕捉到所有的例外:


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"捕捉所有例外: {e}")
except ApplicationError as e: # 此代碼永遠不會執行
    print(f"應用程序通用例外: {e}")

except ApplicationError 塊中捕捉例外的永遠不會發生,因為 except Exception 塊將捕捉所有類型為 Exception 的例外及其子類。

解決方案

因此,例外捕捉的順序應該是與繼承相反的:離 Exception 類越近的類越低。

示例:


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"發生了例外: {e}")
except ApplicationError as e:
    print(f"應用程序通用例外: {e}")
except Exception as e:
    print(f"捕捉所有例外: {e}")

在這個示例中,except 塊的順序與它們的繼承結構相對應:首先捕捉更具體的例外,例如 NegativeValueError,然後是更泛型的,如 ApplicationError。這樣可以正確處理例外,避免當更普遍的處理程序在更專門的 except 塊有機會處理之前捕捉到例外。

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION