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

[经验分享] Python学习笔记总结(四):异常处理

[复制链接]

尚未签到

发表于 2018-8-5 14:11:02 | 显示全部楼层 |阅读模式
  一、异常基础
  1、基础
  try/except/else:【else是可选的】捕捉由代码中的异常并恢复,匹配except里面的错误,并执行except中定义的代码,后继续执行程序(发生异常后,由except捕捉到异常后,不会中断程序,继续执行try语句后面的程序)
  try首行底下的代码块代表此语句的主要动作:试着执行的程序代码。except分句定义try代码块内引发的异常处理器,而else分句(如果有)则是提供没有发生异常时候要执行的处理器。
  try/finally: 无论异常是否发生,都执行清理行为 (发生异常时程序会中断程序,只不过会执行finally后的代码)
  raise: 手动在代码中接触发异常。
  assert: 有条件地在程序代码中触发异常。 assert几乎都是用来收集用户定义的约束条件
  with/as 在Python2.6和后续版本中实现环境管理器。
  用户定义的异常要写成类的实例,而不是字符串、。
  finally可以和except和else分句出现在相同的try语句内、
  扩展
  try/except/finally
  可以在同一个try语句内混合except和finally分句:finally一定回执行,无论是否有异常引发,而且不也不管异常是否被except分句捕捉到。finally有没有异常都执行
  try/except/else:
  except捕捉到对应的异常才执行。else 没有异常才执行、
  也就是说except分句会捕捉try代码块执行时所有发生的任何异常,而else分句只在try代码执行没有发生异常时才执行,finally分句无法释放发生异常都执行。
  2、try语句分句形式
  分句形式            说明
  except:                捕捉所有(其他)异常类型
  except name:        只捕捉特定的异常
  except name,value:    捕捉所有的异常和其额外的数据(或实例)
  except (name1,name2) 捕捉任何列出的异常
  except (name1,name2),value: 捕捉任何列出的异常,并取得其额外数据
  else:                如果没有引发异常,就运行
  finally:            总是会运行此代码块,无论是否发生异常
  空的except分句会捕捉任何程序执行时所引发的而未被捕捉到的异常。要取得发生的实际异常,可以从内置的
  sys模块取出sys.exc_info函数的调用结果。这会返回一个元组,而元组之前两个元素会自动包含当前异常的名称,
  以及相关的额外数据(如果有)。就基于类的异常而言,这两个元素分别对应的是异常的类以及引发类的实例。
  sys.exc_info结果是获得最近引发的异常更好的方式。如果没有处理器正在处理,就返回包含了三个None值的元组。
  否则,将会返回(type,value和traceback)
  *type是正在处理的异常的异常类型(一个基于类的异常的类对象)
  *value是异常参数(它的关联值或raise的第二个参数,如果异常类型为类对象,就一定是类实例)
  *traceback是一个traceback对象,代表异常最初发生时所调用的堆栈。
  3、try/else分句
  不要将else中的代码放入try:中。保证except处理器只会因为包装在try中代码真正的失败而执行,而不是为else中的情况行为失败而执行。
  else分句,让逻辑封明确
  4、try/finally分句
  python先运行try: 下的代码块:
  如果try代码块运行时没有异常发生,Python会跳至finally代码块。然后整个try语句后继续执行下去。
  如果try代码块运行时有发生异常,Python依然会回来运行finally代码块,但是接着会把异常向上传递到较高的try语句或顶层的默认处理器。程序不会在try语句继续执行。
  try:
  Uppercase(open('/etc/rc.conf'),output).process()
  finally:
  open('/etc/rc.conf').close
  5、统一try/except/finally分句
  2.5版本后可统一(包括2.5版本)
  try:
  main-action:
  except Exception1:
  hander1
  except Exception2:
  hander2
  ...
  else:
  else-block
  finally:
  finally-block
  这语句中main-action代码会先执行。如果该程序代码(main-action)引发异常,那么except代码块都会逐一测试,寻找与抛出的异常相符的语句。如果引发异常
  的是Exception1则会执行hander1代码块,如果引发异常的是Exception2,则会执行hander2代码块。以此类推。如果没有引发异常,将会执行else-block代码块。
  无论前面发生什么,当main-action代码块完成时。finally-block都会执行。
  6、通过嵌套合并except和finally
  try:
  try:
  main-action:
  except Exception1:
  hander1
  except Exception2:
  hander2
  ...
  else:
  else-block
  finally:
  finally-block
  和5的效果一样
  7、raise语句
  要故意触发异常,可以使用raise语句。raise语句组成是: raise关键字,后面跟着要引发的异常名称(选用),以及一个可选的额外的数据项,后可随着异常传递
  raise <name>
  raise <name>,<data>
  raise
  第二种形式随着异常传递额外的数据项,在raise语句中,数据是列在异常名称的后面的;在try语句中,取得该数据是通过引入一个进行接收
  它的变量实现的。例如,如果try引入一个exceptname,X:语句,则变量X就会被赋值为raise内所列出的额外的数据项,如果没有定义默认接受到
  的就是特殊对象None。一旦被程序中任意的except分句捕捉,异常就死了(也就是说,不会传递给另一个try),除非又被另一个raise语句或
  错误所引发。现在用户定义的异常应该是类实例对象。
  8、assert语句
  assert可以有条件地在程序代码中触发异常,可以认为是有条件的raise.
  牢记:assert几乎都是用来收集用户定义的约束条件,而不是捕捉内在的程序设计错误。因为Python会自动收集程序的设计错误,通常没有必要写
  assert去捕捉超出索引值,类型不匹配以及除数为0之类的事
  该语句形式:
  assert  <test>,<data>
  实例
  >>> def f(x):
  ...     assert x>0,'x must be great zerot'
  ...     return x**2
  二、异常对象
  Python2.5版本 字符串异常会产生'deprecation‘(不建议使用)’警告。python3.0将不再支持字符串异常,python2.7版本已经不再支持。
  所有的异常都是基于类的异常,字符串异常已退出历史舞台。
  1、基于类的异常
  sys.exc_info() 一种抓取最近发生异常的常用方式。
  对基于类的异常而言,其结果中第一个元素就是引发异常类,而第二个是实际引发的实例。
  注意:目前Python的说明文件指出,用户定义的异常最好继承自Exception内置的异常(但不是必须要求)
  在try语句中,捕捉其超类就会捕捉这个类,以及类树中超类下的所有子类:超类会变成异常分类的名称,而子类会变成该分类中特定的
  异常类型。使用异常的超类,这样子类也捕捉到,可以在未来增加函数异常(在子类里),而不影响程序。
  Python2.5以后版本将每个异常都写成类(必须),从异常树顶层继承Exception(非必须)。
  基本原则是:在异常处理器中,通常来说具体要优于一般。
  2、内置Exception类
  Python把内置异常组织成层次,来支持各种捕捉模式
  Exception:    异常的顶层根超类
  StandardError:    所有内置错误异常的超类
  ArithmeticError:    所有数值错误的超类
  OverflowError:    识别特定的数值错误的子类
  可以在Python库手册或exceptionsn模块的帮助文本中查阅。
  >>> import exceptions
  >>> help(exceptions)
  3、定义异常文本
  对基于类的异常而言,其结果中第一个元素就是引发异常类,而第二个是实际引发的实例
  >>> raise MyBad():
  >>> raise MyBad()
  Traceback (most recent call last):
  File &quot;<stdin>&quot;, line 1, in <module>
  __main__.MyBad: <__main__.MyBad instance at 0x2850d26c>
  这样的显示不友好。改进显示,可以在类中定义__repr__或__str__显示字符串重载方法,从而返回异常达到想要默认处理器显示字符串。

  >>>>  ...     def __repr__(self):
  ...             return &quot;Sorry--my mistake!&quot;
  ...
  >>> raise MyBad()
  Traceback (most recent call last):
  File &quot;<stdin>&quot;, line 1, in <module>
  __main__.MyBad: Sorry--my mistake
  这样把显示类的实例改为了我们定义的文本。
  注意:如果继承自内置异常类,错误测试会有细微的改变,构造方法参数会自动存储并显示在消息中。【同样也可以把继承的重载】

  >>>>  ... >>> raise MyBad()
  Traceback (most recent call last):
  File &quot;<stdin>&quot;, line 1, in <module>
  __main__.MyBad
  >>> raise MyBad('the','bright','side','of')
  Traceback (most recent call last):
  File &quot;<stdin>&quot;, line 1, in <module>
  __main__.MyBad: ('the', 'bright', 'side', 'of')
  4、发送额外数据和实例行为
  把环境信息附加在基于类的异常的办法是:在引发的实例对象中填写实例的属性,通常是在类的构造器方法中。在异常处理器中,是列出
  要赋值为引发的实例的变量,然后通过这个变量名来读取附加的转改信息,并且调用任何基础的类方法。【很强大的功能】

  >>>>  ...     def __init__(self,line,file):
  ...             self.line=line
  ...             self.file=file
  >>> def parser():
  ...     raise FormatError(42,file='diege.txt') #手动定义异常,基于类的异常,类构造函数传递两个数据。
  ...
  >>> try:
  ...     parser()
  ... except FormatError,X: #定义接受异常(类的实例-异常引发时产生的实例)传递过来数据的变量。
  ...     print 'Error at',X.file,X.line #显示实例传递过来的数据
  ...
  Error at diege.txt 42
  5、raise的一般形式
  raise string #基于字符串的异常,已过时
  raise string,data #基于字符串的异常,已过时
  raise instance    #最常用的模式,直接接一个实例:raise FormatError(42,file='diege.txt')

  raise>  raise
  为了和内置异常为字符串的的旧版兼容,也可以

  raise>
  raise>
  raise clase(arg1,arg2,...) #same as:raise>
  这些都相当于raise>  >>> def parse():
  ...     raise FormatError,(42,'diege.txt')
  三、异常的设计
  1、嵌套异常处理器
  把内部的try写成函数来嵌套
  使用语法嵌套
  2、异常的习惯用户
  1)异常不总是错误
  3、核心语言总结
  一般而言,Python提供了一个有层次的工具集。
  内置工具:
  像字符串,列表和字典这些内置类型,会让编写程序更为迅速。
  Python扩展:
  就更重要的任务来说,可以编写自己的函数,模块以及类来扩展Python
  已编译的扩展:
  Python的工具箱类型。
  分类        例子
  对象类型    列表,字典,文件和字符串
  函数        len,range,apply,open

  异常       >  模块        os,TKinter,pickle,re
  属性        __dict__,__name__,__class__
  外部工具    NumPY,SWIG,Jython,IronPython

运维网声明 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-547084-1-1.html 上篇帖子: python 默认编码的理解与设置 下篇帖子: Python: 字符编码基础及中文乱码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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