异常类型
语法错误
print "hello world"
>>SyntaxError: Missing parentheses in call to 'print'
运行错误 | 类型 | 含义 | 实例 | | —- | —- | —- | | AssertionError | 当 assert 关键字后的条件为假时,程序运行会停止并抛出 AssertionError 异常 | | | AttributeError | 当试图访问的对象属性不存在时抛出的异常 | | | IndexError | 索引超出序列范围会引发此异常 | | | KeyError | 字典中查找一个不存在的关键字时引发此异常 | | | NameError | 尝试访问一个未声明的变量时,引发此异常 | | | TypeError | 不同类型数据之间的无效操作 | | | ZeroDivisionError | 除法运算中除数为 0 引发此异常 | |
异常处理
try…except语句块
- 首先执行 try 中的代码块,如果执行过程中出现异常,系统会自动生成一个异常类型,并将该异常提交给 Python 解释器,此过程称为捕获异常。
- 当 Python 解释器收到异常对象时,会寻找能处理该异常对象的 except 块,如果找到合适的 except 块,则把该异常对象交给该 except 块处理,这个过程被称为处理异常。如果 Python 解释器找不到处理异常的 except 块,则程序运行终止,Python 解释器也将退出。
try:
a = int(input('输入被除数'))
b = int(input('输入除数'))
c = a/b
print('您输入的俩个数相除的结果是:',c)
except(ValueError,ArithmeticError):
print('程序发生了数字格式异常、算术异常之一')
except:
print('未知异常')
print('程序继续运行')
获取特定异常的有关信息
每种异常类型都提供了如下几个属性和方法,通过调用它们,就可以获取当前处理异常类型的相关信息:
- args:返回异常的错误编号和描述字符串;
- str(e):返回异常信息,但不包括异常信息的类型,这个和直接输出e结果一样;
- repr(e):返回较全的异常信息,包括异常信息的类型。
```python
try:
1/0
except Exception as e:
访问异常的错误编号和详细信息
print(e.args) print(str(e)) print(repr(e))(‘division by zero’,) division by zero ZeroDivisionError(‘division by zero’)
<a name="thGfO"></a>
### try...except...else...finally
正常执行的程序在try下面执行,在执行中如果发生了异常,则中断当前执行然后执行except中的部分,如果没有异常即不执行except的情况下,则会执行else中的语句,finally语句是最后无论是否有异常都要执行的代码。如果没有except,不能写else和finally。
```python
try:
result = 20 / int(input('请输入除数:'))
print(result)
except ValueError:
print('必须输入整数')
except ArithmeticError:
print('算术错误,除数不能为 0')
else:
print('没有出现异常')
finally:
print('执行完成')
print("继续执行")
>>请输入除数: 3
>>6.666666666666667
>>没有出现异常
>>继续执行
raise用法
基本语法
raise [exceptionName[(reason)]]
其中,用 [] 括起来的为可选参数,其作用是指定抛出的异常名称,以及异常信息的相关描述。如果可选参数全部省略,则 raise 会把当前错误原样抛出;如果仅省略 (reason),则在抛出异常时,将不附带任何的异常描述信息.
基本用法
- raise:单独一个 raise。该语句引发当前上下文中捕获的异常(比如在 except 块中),或默认引发 RuntimeError 异常。
- raise 异常类名称:raise 后带一个异常类名称,表示引发执行类型的异常。
- raise 异常类名称(描述信息):在引发指定类型的异常的同时,附带异常的描述信息。
```python
raise
> RuntimeError Traceback (most recent call last)
in ——> 1 raise
RuntimeError: No active exception to reraise raise ZeroDivisionError
> ZeroDivisionError Traceback (most recent call last)
in ——> 1 raise ZeroDivisionError
ZeroDivisionError: raise ZeroDivisionError(‘除数不能为零’)
> ZeroDivisionError Traceback (most recent call last)
in ——> 1 raise ZeroDivisionError(“除数不能为零”)
ZeroDivisionError: 除数不能为零
```python
try:
a = input("输入一个数:")
#判断用户输入的是否为数字
if(not a.isdigit()):
raise ValueError("a 必须是数字")
except ValueError as e:
print("引发异常:",repr(e))
>>s
>>引发异常: ValueError('a 必须是数字')
try:
a = input("输入一个数:")
if(not a.isdigit()):
raise ValueError("a 必须是数字")
except ValueError as e:
print("引发异常:",repr(e))
raise
>>>
输入一个数: ds
引发异常: ValueError('a 必须是数字')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-41-8ee213d8d387> in <module>
2 a = input("输入一个数:")
3 if(not a.isdigit()):
----> 4 raise ValueError("a 必须是数字")
5 except ValueError as e:
6 print("引发异常:",repr(e))
ValueError: a 必须是数字
当在没有引发过异常的程序使用无参的 raise 语句时,它默认引发的是 RuntimeError 异常。例如:
try:
a = input("输入一个数:")
if(not a.isdigit()):
raise
except RuntimeError as e:
print("引发异常:",repr(e))
>>输入一个数: ds
>>引发异常: RuntimeError('No active exception to reraise')
sys.exc_info()方法:获取异常信息
模块 sys 中,有两个方法可以返回异常的全部信息,分别是 exc_info() 和 last_traceback(),这两个函数有相同的功能和用法,本节仅以 exc_info() 方法为例。
exc_info()方法
exc_info() 方法会将当前的异常信息以元组的形式返回,该元组中包含 3 个元素,分别为 type、value 和 traceback,它们的含义分别是:
- type:异常类型的名称。
- value:捕获到的异常实例。
traceback:是一个 traceback 对象。
import sys
try:
x = int(input("请输入一个被除数"))
print("30除以",x,"等于",30/x)
except:
print(sys.exc_info())
print("其它异常...")
>>>
请输入一个被除数: 0
(<class 'ZeroDivisionError'>, ZeroDivisionError('division by zero'), <traceback object at 0x0000019F451170C0>)
其他异常...
第 2 行是抛出异常的全部信息,这是一个元组,有 3 个元素,第一个元素是一个 ZeroDivisionError 类;第 2 个元素是异常类型 ZeroDivisionError 类的一个实例;第 3 个元素为一个 traceback 对象。其中,通过前 2 个元素可以看出抛出的异常类型以及描述信息,对于第 3 个元素,是一个 traceback 对象,无法直接看出有关异常的信息,还需要对其做进一步处理。
要查看traceback对象包含的内容,需要引进trackback模块
该模块提供了一个标准接口,用于提取,格式和打印Python程序的堆栈痕迹。 它完全模仿了Python解释器在打印堆栈跟踪时的行为。 当您想在程序控制下打印堆栈迹线时,这非常有用,例如在解释器周围的“包装器”中。traceback.print_tb(tb, limit=None, file=None)
1.tb: 这个就是traceback object, 是我们通过sys.exc_info获取到的
2.limit: 这个是限制stack trace层级的,如果不设或者为None,就会打印所有层级的stack trace
3.file: 这个是设置打印的输出流的,可以为文件,也可以是stdout之类的file-like object。如果不设或为None,则输出到sys.stderr。
import sys
import traceback
try:
x = int(input("请输入一个被除数"))
print("30除以",x,"等于",30/x)
except:
trackbace.print_tb(sys.exc_info()[2])
print("其它异常")
>>>
请输入一个被除数 0
其它异常
File "<ipython-input-46-4d6f7e4107ab>", line 5, in <module>
print("30除以",x,"等于",30/x)
- traceback.print_exception(exc_type,exc_value,traceback_error,limit=None,file=sys.stderr) ```python import sys import traceback
try: x = int(input(‘请输入一个数’)) result = 30/x print(result) except Exception as e: exc_type,exc_value,traceback_error = sys.exc_info() print(traceback.print_exception(exc_type,exc_value,traceback_error,limit=3,file=sys.stderr))
> Traceback (most recent call last): File “.\demo.py”, line 6, in
result = 30/x ZeroDivisionError: division by zero None ```
- traceback.print_exc()为print_exception自动填充sys.exc_info()的三个参数
- traceback.format_exc(imit=None, chain=True),返回一个字符串 ```python import sys import traceback
try: x = int(input(‘请输入一个数’)) result = 30/x print(result) except Exception as e:
#exc_type,exc_value,traceback_error = sys.exc_info()
print(traceback.format_exc())
```