目录
一、python中的异常用法
异常是指程序运行过程中出现的非正常状态。在Python编程中,异常通过异常对象来表示。当程序在编译或运行时遇到错误,执行流程会发生变化,抛出异常对象,程序流进入异常处理阶段。对于Python解释器而言,一旦抛出异常,程序会立即停止并输出错误信息。然而,Python允许程序员捕获这些异常并进行处理,从而使程序能够继续执行。
1.1 try-except
如果我们预知可能发生的异常类型,可以使用异常捕获机制来截获这些异常。例如,变量`a`未定义,直接打印会引发错误,但通过异常处理,情况会有所不同。
try:
print(a)
except NameError:
pass
print("123")
运行上述代码时,不会显示任何错误,因为我们使用`except`捕获了`NameError`异常。`pass`语句表示执行了相应的操作,但实际上什么也不做。这样,程序能够继续执行并打印出"123"。`except`后面跟随的是要捕获的异常类型。再看下面的例子:
try:
list1 = [1, 2, 3, 4, 5]
print(list1[5])
except NameError:
pass
print('hehe')
在这段代码中,列表访问越界,但由于捕获的是名称异常,程序仍然会中断。常用的捕获格式如下:
try:
<语句> #运行别的代码
except <名字>:
<语句> #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句> #如果引发了'name'异常,获得附加的数据
else:
<语句> #如果没有异常发生
1.2 异常处理流程:
1. 如果在运行时发生异常,解释器会查找相应的处理语句。
2. 如果在当前函数中未找到处理语句,异常会被传递给上层调用函数,以查看是否能被处理。
3. 如果在最外层仍未找到处理语句,解释器会退出,并打印出traceback,以便用户识别错误原因。
程序员还可以使用raise主动抛出异常,让`except`捕获,如下所示:
name = input("please input name:")
if name == 'hello':
raise NameError('input name error!')
1.3 try-finally
在Python中,异常处理还包括`try-finally`语句。无论是否捕获到错误,`finally`块中的代码都会被执行。这在需要清理资源(如关闭文件、断开网络连接等)时非常有用。
try:
# 一些可能会引发异常的代码
pass
finally:
# 清理资源的代码
pass
通过这种方式,我们可以确保在任何情况下,资源都能得到适当的清理。
1.4 使用`except`是否指定异常
使用`except`而不指定任何异常类型
你可以在不指定任何异常类型的情况下使用`except`,如下所示:
try:
# 正常的操作
# ......................
except:
# 发生异常时执行的代码块
# ......................
else:
# 如果没有异常执行的代码块
# ......................
这种方式的`try-except`语句会捕获所有发生的异常。然而,这不是一个推荐的做法,因为它无法让我们识别出具体的异常信息。由于它会捕获所有的异常,这可能导致难以调试和定位问题。
使用`except`并指定多种异常类型
你也可以使用同一个`except`语句来处理多种异常,如下所示:
try:
# 正常的操作
# ......................
except (Exception1, Exception2, ..., ExceptionN):
# 发生上述多个异常中的任何一个时执行的代码块
# ......................
else:
# 如果没有异常执行的代码块
# ......................
通过这种方式,你可以更精确地处理特定的异常,从而提高代码的可读性和可维护性。
二、异常的参数
一个异常可以携带参数,这些参数可以作为输出的异常信息。
你可以通过`except`语句来捕获异常及其参数,如下所示:
try:
# 正常的操作
# ......................
except ExceptionType as Argument:
# 你可以在这里输出 Argument 的值...
变量接收的异常值通常包含在异常的语句中。在元组的形式中,变量可以接收一个或多个值。
元组通常包含错误字符串、错误数字、错误位置等信息。
### 实例
以下是一个捕获单个异常的实例:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 定义函数
def temp_convert(var):
try:
return int(var)
except ValueError as Argument:
print("参数没有包含数字\n", Argument)
# 调用函数
temp_convert("xyz")
以上程序执行结果如下:
$ python test.py
参数没有包含数字
invalid literal for int() with base 10: 'xyz'
在这个例子中,`temp_convert`函数尝试将输入的字符串转换为整数。如果输入的字符串不能转换为整数(例如"xyz"),则会引发`ValueError`异常,并且异常的参数会被捕获并打印出来。
三、自定义异常
在Python中,你可以通过创建一个新的异常类来定义自己的异常。自定义异常类通常继承自内置的`Exception`类或其他更具体的异常类。以下是如何创建和使用自定义异常的基本步骤:
1. **定义自定义异常类**:
创建一个新的类,继承自`Exception`或其子类。
2. **添加构造函数**:
通常,自定义异常类会包含一个构造函数,用于接收错误信息并将其存储在实例变量中。
3. **使用自定义异常**:
在代码中引发自定义异常,并使用`try-except`块捕获和处理它。
以下是一个简单的示例:
# 定义自定义异常类
class MyCustomError(Exception):
def __init__(self, message):
super().__init__(message)
self.message = message
# 使用自定义异常
def divide(a, b):
if b == 0:
raise MyCustomError("除数不能为零")
return a / b
# 捕获和处理自定义异常
try:
result = divide(10, 0)
except MyCustomError as e:
print(f"捕获到自定义异常: {e}")
else:
print(f"结果是: {result}")
在这个示例中:
1. `MyCustomError`是一个自定义异常类,继承自`Exception`。
2. `MyCustomError`类的构造函数接收一个错误信息,并调用父类的构造函数来初始化它。
3. `divide`函数在除数为零时引发`MyCustomError`异常。
4. 使用`try-except`块捕获并处理`MyCustomError`异常,打印错误信息。
通过这种方式,你可以创建具有特定含义的自定义异常,使代码更具可读性和可维护性。