Python-异常处理
0 前言
1 输入检查
1.1 输入数据类型检查
调用python内置函数时,如果参数个数不对或参数类型不对,python解释器会自动检查出来;
而调用自己写的函数时,python可以检查出参数个数不对,但不能检查出参数类型:
数据类型检查可以使用内置函数isinstance()
实现,内置函数isinstance
有两个参数,第一个参数是待检测的对象,第二个参数是对象类型,可以是单个类型,也可以是元组,返回的bool
类型
def my_abs(x):
if not isinstance(x, (int, float)):
raise TypeError('bad operand type')
if x>=0:
return x
else:
return -x
1.2 输入字符串检查
- 如果字符串str所有字符都是数字,
str.isdigit()
返回结果就是True
S1 = '12345' #纯数字
S2 = '①②' #带圈的数字
print(S1.isdigit())
print(S2.isdigit())
>>>True
>>>True
- 如果字符串str所有字符都是字母(包括汉字),
str.isalpha()
返回结果就是True
S1 = 'abc汉字' #汉字+字母
S2 = 'ab字134' #包含数字
print(S1.isalpha())
print(S2.isalpha())
>>>True
>>>False
- 如果字符串str所有字符都是字母和数字,
str.isalnum()
返回结果就是True
S1 = 'abc汉字1' #字母+汉字+数字
print(S1.isalnum())
>>>True
- 如果字符串str所有字符都是空白符
\t``\n``\r
,str.isspace()
返回结果就是True
S1 = 'abc汉字1' #字母+汉字+数字
print(S1.isspace())
>>>False
2 异常捕捉
异常就是程序运行时候发生错误的信号(在程序出现错误的时候,则会产生一个异常,若程序没有处理他,则会抛出该异常,程序的运行也随之终止)
Python可以自动捕捉异常,但是程序也会中断。我们可以自己写异常捕捉,让程序在异常后继续进行
2.1 标准异常
BaseException 所有异常的基类
+-- SystemExit 解释器请求退出
+-- KeyboardInterrupt 用户中断执行(通常是输入^C)
+-- GeneratorExit 生成器(generator)发生异常来通知退出
+-- Exception 常规错误的基类
+-- StopIteration 迭代器没有更多的值
+-- Warning 警告的基类
| +-- DeprecationWarning 关于被弃用的特征的警告
| +-- FutureWarning 关于构造将来语义会有改变的警告
| +-- OverflowWarning 旧的关于自动提升为长整型(long)的警告
| +-- PendingDeprecationWarning 关于特性将会被废弃的警告
| +-- RuntimeWarning 可疑的运行时行为(runtime behavior)的警告
| +-- SyntaxWarning 可疑的语法的警告
| +-- UserWarning 用户代码生成的警告
+-- StandardError 所有的内建标准异常的基类
+-- ArithmeticError 所有数值计算错误的基类
| +-- FloatingPointError 浮点计算错误
| +-- OverflowError 数值运算超出最大限制
| +-- ZeroDivisionError 除(或取模)零 (所有数据类型)
+-- AssertionError 断言语句失败
+-- AttributeError 对象没有这个属性
+-- EOFError 没有内建输入,到达EOF 标记
+-- EnvironmentError 操作系统错误的基类
| +-- IOError 输入/输出操作失败
| +-- OSError 操作系统错误
| | +-- WindowsError 系统调用失败
+-- ImportError 导入模块/对象失败
+-- LookupError 无效数据查询的基类
| +-- IndexError 序列中没有此索引(index)
| +-- KeyError 映射中没有这个键
+-- MemoryError 内存溢出错误(对于Python 解释器不是致命的)
+-- NameError 未声明/初始化对象 (没有属性)
| +-- UnboundLocalError 访问未初始化的本地变量
+-- ReferenceError 弱引用(Weak reference)试图访问已经垃圾回收了的对象
+-- RuntimeError 一般的运行时错误
| +-- NotImplementedError 尚未实现的方法
+-- SyntaxError Python 语法错误
| +-- IndentationError 缩进错误
| | +-- TabError Tab和空格混用
+-- SystemError 一般的解释器系统错误
+-- TypeError 对类型无效的操作
+-- ValueError 传入无效的参数
+-- UnicodeError Unicode 相关的错误
+-- UnicodeDecodeError Unicode 解码时的错误
+-- UnicodeEncodeError Unicode 编码时错误
+-- UnicodeTranslateError Unicode 转换时错误
2.2 try…except…
如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句
- 捕捉特定异常
第一个符合条件的except语句会被执行,可以用于报告错误。如果仅仅是报告错误,程序依然会停止
a = 0
try:
b = 5/a
except ZeroDivisionError as err:
print('Error: a不能为0')
except ValueError as err:
print('Error: 传入参数无效')
- 捕捉所有异常
except语句后面Exception表示捕获任何异常类型
a = 0
try:
b = 5/a
except Exception as err:
print('a不能为0')
- 异常补救
except语句后面对可能的异常进行补救,比如预设文件地址找不到时,要求手动指定文件地址
a = 0
try:
b = 5/a
except:
b = 0
- 带异常说明
所以的标准异常都带有一段文字说明,在捕捉到异常时,可以把文字说明同时捕捉
a = 0
try:
b = 5/a
except Exception,err:
print 'Error: a不能为0\n' err
>>>Error: a不能为0
>>>'integer division or modulo by zero'
2.3 try…except…else…
如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句
- else语句可以在程序正确经过,某个节点时也进行报告
try:
f = open('file', 'w')
except IOError:
print('Error: 没有找到文件或读取文件失败')
else:
print('内容写入文件成功')
f.close()
3 手动触发异常
我们可以使用raise语句自己触发异常
def function(a):
if a == 0:
raise Exception("Error: a不能为0")
try:
function(0)
except Exception,err:
print err
>>>Error: a不能为0
4 输出异常信息
捕获异常err后,可以获得异常的名称,并且通过sys模块获得当前的文件、函数和行号,可以选择这些信息发送到控制台或者log文件
异常信息err可以通过err.__class__.__name__
获得异常类型,所以实际使用中只要捕获Exception
异常就行
def log(err):
err_file = sys._getframe().f_back.f_code.co_filename # 调用log的文件名
err_line = sys._getframe().f_back.f_lineno # 调用log的行号
err_func = sys._getframe().f_back.f_code.co_name # 调用log的函数名
info = err.__class__.__name__ + ': ' + str(err) + '\n' err的名称
info = info + 'File: ' + err_file + ' '
info = info + 'Line: ' + str(err_line) + ' '
info = info + 'Function: ' + err_func + '()\n'
info = info + '--------------------------------------------\n'
print(info) # 显示到控制台
with open(self.path, 'a', encoding='utf-8', errors='ignore') as f:
f.write(info) # 写入log文件
if __name__ == '__main__':
try:
with open('不存在的文件', 'r', encoding='utf-8', errors='ignore') as f:
except Exception as err:
log(err)
结果为:
>>>FileNotFoundError: [Errno 2] No such file or directory: '不存在的文件'
>>>File: D:\6_SoftwareTest\Template\base.py Line: 51 Function: >>>myReadFile()
--------------------------------------------