设为首页 收藏本站
查看: 889|回复: 0

[经验分享] Python自动化运维之异常处理

[复制链接]

尚未签到

发表于 2018-8-4 09:32:21 | 显示全部楼层 |阅读模式
  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尚未实现的方法SyntaxErrorPython 语法错误IndentationError缩进错误TabErrorTab 和空格混用SystemError一般的解释器系统错误TypeError对类型无效的操作ValueError传入无效的参数UnicodeErrorUnicode 相关的错误UnicodeDecodeErrorUnicode 解码时的错误UnicodeEncodeErrorUnicode 编码时错误UnicodeTranslateErrorUnicode 转换时错误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
  异常处理用于处理程序错误之外,还有许多应用的地方。如关闭资源、平台兼容、模块导入等。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-546282-1-1.html 上篇帖子: Python随笔(四)、python基础 下篇帖子: python列表的使用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表