在 Python 中创建自定义异常
本教程将演示你可以在 Python 中创建自定义异常类。在这里,我们将展示如何正确执行异常处理、定义自定义异常类以及覆盖现有的内置异常。
异常是一种事件,每当程序中的某些内容未按预期运行或中断程序预期用例的流程时就会发生。如果没有异常处理,程序将完全停止执行,并且必须修复或处理异常。
在 Python 中创建自定义异常类
在 Python 中创建异常类的方式与创建常规类的方式相同。主要区别在于你必须包含 Python 的基类 Exception
以通知编译器你正在创建的类是异常类。
让我们测试这个方法以创建一个名为 DemoException
的异常类,并在内部使用占位符控制流关键字 pass
作为占位符。
class DemoException(Exception):
pass
在 Python 中使用关键字 raise
执行异常引发
要测试 DemoException
类并查看它在实际触发时显示的内容,请执行异常引发。异常引发与其他编程语言中的异常抛出同义。
使用关键字 raise
,使用给定的异常类触发异常并输出异常消息。
class DemoException(Exception):
pass
raise DemoException
输出:
Traceback (most recent call last):
File "/Users/demo/python/demo_exception.py", line 4, in <module>
raise DemoException
__main__.DemoException
如果未声明自定义异常消息,则终端中将显示标准异常。
在 Python 中声明自定义异常消息
要为 DemoException
声明自定义异常消息,请覆盖异常类的 __init__()
方法,并在参数中包含应为异常输出的消息,以及强制自引用参数 self
。
例如,让我们覆盖 __init__()
方法并为 DemoException
类创建自定义消息:
class DemoException(Exception):
def __init__(self, message):
super().__init__(message)
请注意,要成功地将消息集成到你的异常中,请调用基本 Exception
类、__init__()
方法,并将 message
作为参数包含在内。
让我们再次使用 raise
关键字调用异常类,现在,使用它传递自定义消息:
class DemoException(Exception):
def __init__(self, message):
super().__init__(message)
message = "Exception Triggered! Something went wrong."
raise DemoException(message)
输出应如下所示:
Traceback (most recent call last):
File "/Users/demo/python/helloworld.py", line 6, in <module>
raise DemoException(message)
__main__.DemoException: Exception Triggered! Something went wrong.
我们现在已经成功创建并触发了一个带有自定义错误消息的异常类。
对于可能触发异常的实际情况,我们如何处理和引发这些异常?你可以通过使用 try...except
块实现异常处理来巧妙地解决这个问题。
使用 Python 中的 try...except
块执行异常处理
try...except
块很像 Java 等其他语言中的 try-catch
块。
try...except
块有 2 个主要块和 2 个可选块:
try
(必需)- 负责封装可能触发异常的代码块的主块。每当触发异常时,try
块就会停止其中的整个过程。except
(必需)- 每当触发指定的异常时,块程序就会继续进行。此块通常包含调用者的描述性错误消息或只是一个简单的print()
语句。在一个try
块中可能有多个except
块,每个块都捕获不同的异常。else
(可选) - 如果try
块没有触发任何异常,这个可选块是程序将继续的地方。finally
(可选)- 无论是否触发异常,此可选块都会在前 3 个块中的所有内容都执行完毕后运行。
让我们使用前面使用 DemoException
类的示例来尝试一个简单的 try...except
块。
首先,将 raise
关键字包装在一个函数中,并将其放入 try...except
块中。
我们将为此示例创建的函数是一个函数,它接受一个数字并在它发送 0
时抛出异常。如果它发送任何其他号码,则代码将按预期进行。参考下面的例子:
class DemoException(Exception):
def __init__(self, message):
super().__init__(message)
message = "Exception Triggered! Something went wrong."
def triggerException(num):
if (num == 0):
raise DemoException(message)
else:
print(num)
try:
triggerException(0)
print("Code has successfully been executed.")
except DemoException:
print("Error: Number should not be 0.")
由于 triggerException()
将 0
作为参数传递,代码应该触发 DemoException
。在这里,我们应该期望 raise
关键字消息被 except
块内的任何内容作为输出覆盖。
请注意,未输出 triggerException()
函数调用后的 print()
行。这是因为函数引发了异常;因此,它立即停止了 try
块中的所有进程,并直接进入 except
块。
输出:
Error: Number should not be 0.
现在,让我们尝试传递一个有效的数字,例如 20
。
try:
triggerException(20)
print("Code has successfully been executed.")
except DemoException:
print("Error: Number should not be 0.")
输出:
20
Code has successfully been executed.
让我们尝试链接 except
块并创建另一个异常。让我们调用新的异常 NumberFormatException
,如果给定的输入不是数字就会触发。对于这个异常类,让我们在类中声明消息。
class NumberFormatException(Exception, value):
message = f'{value} is not a number'
def __init__(self):
super().__init__(message)
现在,修改上面的代码来处理新的异常类 NumberFormatException
:
class DemoException(Exception):
def __init__(self, message):
super().__init__(message)
class NumberFormatException(Exception):
def __init__(self, message, value):
message = f'{value} is not a number'
super().__init__(message)
message = "Exception occured."
def triggerException(num):
if (not num.isdigit()):
raise NumberFormatException(message, num)
elif (num == 0):
raise DemoException(message)
else:
print(num)
num = "sample string"
try:
triggerException(num)
print("Code has successfully been executed.")
except DemoException:
print("Error: Number should not be 0.")
except NumberFormatException:
print(num+" is not a number.")
在这段代码中,传递给 triggerException()
的 num
的值是一个字符串'sample string'
,因此应该触发 NumberFormatException
。
输出:
sample string is not a number.
总之,在 Python 中创建自定义异常就像创建一个新类一样简单,但在类定义中将 Exception
类作为一个额外的参数。raise
关键字用于触发给定异常类的异常。try...except
块用于将一个或多个异常包装在一个代码块中,并在处理该异常时修改代码的作用,而不仅仅是完全关闭程序。
Skilled in Python, Java, Spring Boot, AngularJS, and Agile Methodologies. Strong engineering professional with a passion for development and always seeking opportunities for personal and career growth. A Technical Writer writing about comprehensive how-to articles, environment set-ups, and technical walkthroughs. Specializes in writing Python, Java, Spring, and SQL articles.
LinkedIn