Python自动化运维之异常处理
1、异常
异常就是非正常状态,在Python中使用异常对象来表示异常。若程序在编译或运行过程中发生错误,程序的执行过程就会发生改变,抛出异常对象,程序流进入异常处理。如果异常对象没有被处理或捕捉,程序就会执行回溯(Traceback)来终止程序。
2、异常类型
通用异常类型表
| 异常 | 描述 |
| BaseException | 所有异常的基类 |
| SystemExit | 解释器请求退出 |
| KeyboardInterrupt | 用户中断执行(通常是输入^C) |
| Exception | 常规错误的基类 |
| StopIteration | 迭代器没有更多的值 |
| GeneratorExit | 生成器(generator)发生异常来通知退出 |
| 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 转换时错误 |
| Warning | 警告的基类 |
| DeprecationWarning | 关于被弃用的特征的警告 |
| FutureWarning | 关于构造将来语义会有改变的警告 |
| OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
| PendingDeprecationWarning | 关于特性将会被废弃的警告 |
| RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
| SyntaxWarning | 可疑的语法的警告 |
| UserWarning | 用户代码生成的警告 |
Exception类:是通用异常基类下列异常类均继承于Exception类,python解析器会自动将通用异常类型名称放在内建命名空间中,所以当使用通用异常类型时,不需要import exceptions模块。
3、异常处理
3.1 触发异常raise
raise关键字:手动抛出一个通用的异常类型(Exception),类似Java中的throw语句。raise关键字后跟异常的名称,异常名称能够标识出异常类的对象。执行raise语句时,python会创建指定异常类的对象,还能够指定对异常对象进行初始化的参数,参数也可以为由若干参数组成的元组。
注意:一旦执行raise语句,程序就会被终止。
格式:raise [exceptionType[,argument][,traceback]]
def testRaise(number):
if number < 1:
raise ValueError('Invalid value') #或者 raise ValueError,'Invalid value'
testRaise(0)
traceback:这个参数用于追踪异常对象,一般很少使用。
这样就可以触发一个异常,并且接收异常信息。
3.2 传递异常
当你捕获到异常之后又希望再次的触发异常只需要使用不带任何参数的raise关键字。
import os
try:
openFile = open('notExistsFile.txt','r')
fileContent = openFile.readlines()
except IOError:
print('File not Exists'
if not os.path.exists('notExistsFile.txt'):
raise
except:
print('process exception'
异常会在捕获之后再次触发同一个异常。
3.3 assert语句触发异常
assert语句根据后面的表达式的真假来控制程序流。若为True,则往下执行。若为False,则中断程序并调用默认的异常处理器,同时输出指定的提示信息。
格式:assert expression,'information'
例如:
def testAssert(x):
assert x < 1,'Invalid value'
testAssert(1)
print('Valid value'
执行结果:
AssertionError: Invaild value
3.4 捕获异常try..except..else
注意:except子句的数量没有限制,但使用多个except子句捕获异常时,如果异常类之间具有继承关系,则子类应该写在前面,否则父类将会直接截获子类异常。放在后面的子类异常也就不会执行。
格式:
try: 可能触发异常的语句块 except [exceptionType]: 捕获可能触发的异常[可以指定处理的异常类型] except [exceptionType][,date]: 捕获异常并获取附加数据 except: 没有指定异常类型,捕获任意异常 else: 没有触发异常时,执行的语句块
4、try的工作原理
执行一个try语句时,python解析器会在当前程序流的上下文中作标记,当出现异常后,程序流能够根据上下文的标记回到标记位,从而避免终止程序。
1. 如果try语句执行时发生异常,程序流跳回标记位,并向下匹配执行第一个与该异常匹配的except子句,异常处理完后,程序流就通过整个try语句(除非在处理异常时又引发新的异常)。
2. 如果没有找到与异常匹配的except子句(也可以不指定异常类型或指定同样异常类型Exception,来捕获所有异常),异常被递交到上层的try(若有try嵌套时),甚至会逐层向上提交异常给程序(逐层上升直到能找到匹配的except子句。实在没有找到时,将结束程序,并打印缺省的错误信息)。
3. 如果在try子句执行时没有发生异常,python将执行else语句后的语句(可选),然后控制流通过整个try语句。
try:
openFile = open('notExistsFile.txt','r')
fileContent = openFile.readlines()
except IOError:
print('File not Exists') # 执行
except:
print('process exception') # 不执行
else:
print('Reading the file') # 不执行
执行结果:
In [157]: %run testError.py File not Exists
嵌套try:
try:
try:
openFile = open('notExistsFile.txt','r')
fileContent = openFile.readlines()
except IOError:
print('File not Exists') #执行
except:
print('process exception') #不执行
else:
print('Reading the file') #执行
执行结果:
In [159]: %run testError.py File not Exists Reading the file
5、捕捉多个异常
方法一:指定一个通用异常,可以捕获多个不同的包含在Exception类中的异常类。
try: 语句块 except Exception: 语句块
方法二:在一个except子句后将多个异常作为元组元素列出。
try: 语句块 except (IOError,ValueError): 语句块
方法三:except子句后不带任何异常名称,捕获所有异常
try: 语句块 except: 语句块
6、try..finally语句
无论try语句块中是否触发异常,都会执行finally子句中的语句块,因此一般用于关闭文件或关闭因系统错误而无法正常释放的资源。比如文件关闭,释放锁,把数据库连接返还给连接池等。
import os
def write_test(fileName,content_iterable):
try:
pwd = open(fileName,'w')
for key,value in content_iterable.items():
pwd.write(key+'\t'+value+'\n') #传入String类型参数同时加入换行符
finally:
pwd.close()
if __name__ == '__main__':
fileName = '/usr/local/src/pyScript/fileOperation.txt'
dic = {'name':'Jmilk','age':'23','city':'BJ'}
if os.path.exists(fileName):
write_test(fileName,dic)
else:print('File not exist!')
注意:try..finally与try..except 是可以同时使用的。
In [3]: try:
...: raise
...: except Exception:
...: print('error')
...: raise
...: finally:
...: print('success')
...:
error
success
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-530db52949e7> in <module>()
1 try:
----> 2 raise
3 except Exception:
4 print('error'
5 raise
TypeError: exceptions must be old-style classes or derived from BaseException, not NoneType
NOTE:try…finally 的意义在于,就是我们在 try 代码块中执行了 return 语句,但是仍然会继续执行在 finally 中的代码块,所以我们一般用作处理资源的释放。
7、自定义异常
通过(直接或简介)继承Exception类来创建一个自定义异常类,自定义的异常类只能通过raise关键字来手动触发。
class testError(Exception): #直接集成Exception类
def __init__(self,arg):
self.args = arg
try:
raise testError('Just test')
except testError,info:
print info.args
执行结果:
In [52]: %run test.py
('J', 'u', 's', 't', ' ', 't', 'e', 's', 't')
with..as触发异常自动关闭资源
在使用类文件的流对象时,都需要单独的调用close()来关闭资源。with..as语句能够实现在with语句块执行完后,自动的关闭文件。如果with语句块中触发异常,会调用默认的异常处理器处理,而且文件仍然能够正常关闭。
import os
def testWith(fileName):
try:
with open(fileName,'r+') as pwd:
pwd.readlines()
print 2/0
except Exception:
print('File closed:',pwd.closed #判断文件是否关闭
if __name__ == '__main__':
if os.path.exists('/usr/local/src/pyScript/fileOperation.txt'):
testWith('/usr/local/src/pyScript/fileOperation.txt')
print('continue')
执行结果:
In [17]: %run test.py File closed: True #没有call close()函数,文件仍然自动关闭。 continue
7、as获取异常信息
每个异常都会有一定的描述信息,可以通过as关键字来获取。但是这种异常信息并不适合一般用户阅读,所以会使用自定义的异常信息。但是仍然会将原有的异常信息保留起来,用于后期的异常分析。
try:
try:
openFile = open('notExistsFile.txt','r')
fileContent = openFile.readlines()
except (IOError,ValueError) as info: #或者except (IOError,ValueError),info:
print info
except:
print('process exception')
else:
print('Reading the file')
执行结果:
In [164]: %run testError.py [Errno 2] No such file or directory: 'notExistsFile.txt'
异常参数
也可以使用异常参数作为输出的异常信息参数,来获取异常信息。并且异常参数中包含有异常信息、错误数字、错误位置等属性。
try:
try:
openFile = open('notExistsFile.txt','r')
fileContent = openFile.readlines()
except (IOError,ValueError),info:
print dir(info)
print info.args
except:
print('process exception')
else:
print('Reading the file')
执行结果:
In [44]: %run test.py ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__', 'args', 'errno', 'filename', 'message', 'strerror'] (2, 'No such file or directory') Reading the file
8、traceback追踪异常
使用traceback追踪异常的时候,需要import traceback模块。traceback模块可以有效的帮助查看异常的详细信息。
注意:若希望获取异常的详细信息,却又不会终止程序的执行,可以在except子句中使用
tarceback.print_exc()函数。 tarceback.print_exc(): print_exc(limit=None, file=None) Shorthand for ‘print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback, limit, file)’. (In fact, it uses sys.exc_info() to retrieve the same information in a thread-safe way.)
输出sys.exc_type, sys.exc_value, sys.exc_traceback, limit, file等异常信息,实际上是以线程安全的方式去使用sys.exc_info()函数来获取相同的信息。
import traceback
try:
openFile = open('notExistsFile.txt','r')
fileContent = openFile.readlines()
except IOError as info:
print('File not Exists')
print(info)
traceback.print_exc()
print('continue')
except:
print('process exception')
else:
print('Reading the file')
执行结果:
In [38]: %run test.py
File not Exists
[Errno 2] No such file or directory: 'notExistsFile.txt'
Traceback (most recent call last):
File "/usr/local/src/pyScript/test.py", line 5, in <module>
openFile = open('notExistsFile.txt','r')
IOError: [Errno 2] No such file or directory: 'notExistsFile.txt'
continue
异常信息的重定向:如果希望将异常的信息保存在一个指定的文件中,以供后期分析。可以使用下面的方法:
import traceback
try:
with open('notExistsFile.txt','r') as openFile:
fileContent = openFile.readlines()
except IOError:
with open('errorLog','w+') as errorInfo:
traceback.print_exc(file=errorInfo)
print('continue')
except:
print('process exception')
else:
print('Reading the file')
执行结果:
In [61]: %run test.py
continue
In [62]: cat errorLog
Traceback (most recent call last):
File "/usr/local/src/pyScript/test.py", line 5, in <module>
with open('notExistsFile.txt','r') as openFile:
IOError: [Errno 2] No such file or directory: 'notExistsFile.txt'
sys.exc_info()获取异常信息
traceback.print_exc()函数实际上是call sys.exc_info()
import sys try: a=b b=c except: info=sys.exc_info() print(info[0],":",info[1])
执行结果:
In [65]: %run test.py <type 'exceptions.NameError'> : name 'b' is not defined
异常处理用于处理程序错误之外,还有许多应用的地方。如关闭资源、平台兼容、模块导入等。
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
MySQL主从延迟解决方案
最近一段时间内,无论在博客评论还是私信里,技术老铁们都对老张写的博客表示认可和支持,我很欣慰!从业多年就希望有一天能把自己学过的东西,遇到的问题,分享出来!我们大家一起进步! 今儿打算给大家分享的是如何解决MySQL主从延迟的问题,这个也是一些同学在生产中面临的比较棘手的问题, 经常给我打电话或者微信,说张老师,现在监控主从之间的延迟特别大。怎么办啊?!有什么办法可以避免延迟嘛?! 面对抛出这样的问题,我们先来了解下生产中有哪些主从架构?线上生产环境一般有一主一从,一主多从,多主一丛(级联复制,MySQL5.7之后才有) ,主主复制。主从架构存在目的就是为了故障切换和读写分离。它的原理如下图: 主服务器有一个工作线程 io dump thread 从服务器有两个工作线程,一个是io thread,一个sql thread。 主库把外界接收的SQL请求,记录到自己的binlog日志里面,从库的 io thread去请求主库 的binlog日志,并将得到的binlog日志写到自己的relay log(中继日志) 文件中;主库通过io dump thread,给从库 io thread 传...
-
下一篇
Python3:图片转字符画
防伪码:没有相当程度的孤独是不可能有内心的平和。 1、环境准备 主机名 IP 系统 Python版本 Python-01 192.168.10.9 CentOS release 6.9 (Final) 3.5.4 参考:https://www.shiyanlou.com/courses/370/labs/1191/document 2、原理 字符画是一系列字符的组合,可以把字符看作是比较大块的像素,一个字符能表现一种颜色(暂且这么理解吧),字符的种类越多,可以表现的颜色也越多,图片也会更有层次感。 灰度值:指范围一般从0到255,白色为255,黑色为0,故黑白图片也称灰度图像。 任何颜色都由红、绿、蓝三基色组成,假如原来某点的颜色为RGB(R,G,B),本次实验可以用以下公式来转换灰度: gray=0.2126*r+0.7152*g+0.0722*b 3、实验 本次实验的核心是pillow库的Image模块和argparse模块。 3.1 图像处理库pillow Pillow是Python里的图像处理库,支持Python3.X,提供了广泛的文件格式支持和强大的图像处理能力,主要包括图像...
相关文章
文章评论
共有0条评论来说两句吧...

微信收款码
支付宝收款码