原文: https://www.programiz.com/python-programming/user-defined-exception

在本教程中,您将借助示例学习如何根据需要定义自定义异常。

Python 有许多内置异常,它们会在程序出现问题时强制您的程序输出错误。

但是,有时您可能需要创建自己的自定义异常来满足您的目的。


创建自定义异常

在 Python 中,用户可以通过创建新类来定义自定义异常。 必须从内置的Exception类直接或间接派生此异常类。 大多数内置异常也是从此类派生的。

  1. >>> class CustomError(Exception):
  2. ... pass
  3. ...
  4. >>> raise CustomError
  5. Traceback (most recent call last):
  6. ...
  7. __main__.CustomError
  8. >>> raise CustomError("An error occurred")
  9. Traceback (most recent call last):
  10. ...
  11. __main__.CustomError: An error occurred

在这里,我们创建了一个名为CustomError的用户定义异常,该异常继承自Exception类。 与其他异常一样,可以使用raise语句以及可选的错误消息来引发此新异常。

当我们开发大型 Python 程序时,最好将程序引发的所有用户定义的异常放在单独的文件中。 许多标准模块可以做到这一点。 它们分别将其异常定义为exceptions.pyerrors.py(通常但并非总是如此)。

用户定义的异常类可以实现普通类可以做的所有事情,但是我们通常使它们简单明了。 大多数实现都声明一个自定义基类,并从该基类派生其他异常类。 在下面的示例中,将使该概念更清晰。


示例:Python 中的用户定义异常

在此示例中,我们将说明如何在程序中使用用户定义的异常来引发和捕获错误。

该程序将要求用户输入一个数字,直到他们正确猜出一个存储的数字为止。 为了帮助他们弄清楚,他们的猜测是大于还是小于所存储的数字。

  1. # define Python user-defined exceptions
  2. class Error(Exception):
  3. """Base class for other exceptions"""
  4. pass
  5. class ValueTooSmallError(Error):
  6. """Raised when the input value is too small"""
  7. pass
  8. class ValueTooLargeError(Error):
  9. """Raised when the input value is too large"""
  10. pass
  11. # you need to guess this number
  12. number = 10
  13. # user guesses a number until he/she gets it right
  14. while True:
  15. try:
  16. i_num = int(input("Enter a number: "))
  17. if i_num < number:
  18. raise ValueTooSmallError
  19. elif i_num > number:
  20. raise ValueTooLargeError
  21. break
  22. except ValueTooSmallError:
  23. print("This value is too small, try again!")
  24. print()
  25. except ValueTooLargeError:
  26. print("This value is too large, try again!")
  27. print()
  28. print("Congratulations! You guessed it correctly.")

这是该程序的示例运行。

  1. Enter a number: 12
  2. This value is too large, try again!
  3. Enter a number: 0
  4. This value is too small, try again!
  5. Enter a number: 8
  6. This value is too small, try again!
  7. Enter a number: 10
  8. Congratulations! You guessed it correctly.

我们定义了一个名为Error的基类。

我们程序实际引发的另外两个异常(ValueTooSmallErrorValueTooLargeError)是从此类派生的。 这是在 Python 编程中定义用户定义的异常的标准方法,但不仅限于此。


自定义异常类

我们可以进一步自定义此类,以根据需要接受其他参数。

要了解有关自定义Exception类的信息,您需要具有面向对象编程的基础知识。

访问 Python 面向对象编程,开始学习 Python 中的面向对象编程。

让我们看一个例子:

  1. class SalaryNotInRangeError(Exception):
  2. """Exception raised for errors in the input salary.
  3. Attributes:
  4. salary -- input salary which caused the error
  5. message -- explanation of the error
  6. """
  7. def __init__(self, salary, message="Salary is not in (5000, 15000) range"):
  8. self.salary = salary
  9. self.message = message
  10. super().__init__(self.message)
  11. salary = int(input("Enter salary amount: "))
  12. if not 5000 < salary < 15000:
  13. raise SalaryNotInRangeError(salary)

输出

  1. Enter salary amount: 2000
  2. Traceback (most recent call last):
  3. File "<string>", line 17, in <module>
  4. raise SalaryNotInRangeError(salary)
  5. __main__.SalaryNotInRangeError: Salary is not in (5000, 15000) range

在这里,我们覆盖了Exception类的构造器,以接受我们自己的自定义参数salarymessage。 然后,使用super()self.message参数手动调用父Exception类的构造器。

自定义self.salary属性定义为以后使用。

然后,当引发SalaryNotInRangeError时,将使用Exception类的继承的__str__方法显示相应的消息。

我们也可以通过覆盖__str__方法本身来定制它。

  1. class SalaryNotInRangeError(Exception):
  2. """Exception raised for errors in the input salary.
  3. Attributes:
  4. salary -- input salary which caused the error
  5. message -- explanation of the error
  6. """
  7. def __init__(self, salary, message="Salary is not in (5000, 15000) range"):
  8. self.salary = salary
  9. self.message = message
  10. super().__init__(self.message)
  11. def __str__(self):
  12. return f'{self.salary} -> {self.message}'
  13. salary = int(input("Enter salary amount: "))
  14. if not 5000 < salary < 15000:
  15. raise SalaryNotInRangeError(salary)

输出

  1. Enter salary amount: 2000
  2. Traceback (most recent call last):
  3. File "/home/bsoyuj/Desktop/Untitled-1.py", line 20, in <module>
  4. raise SalaryNotInRangeError(salary)
  5. __main__.SalaryNotInRangeError: 2000 -> Salary is not in (5000, 15000) range

要了解有关如何使用 Python 处理异常的更多信息,请访问 Python 异常处理