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

[经验分享] python的异常处理,以及自定义异常

[复制链接]

尚未签到

发表于 2018-8-5 11:50:44 | 显示全部楼层 |阅读模式
  写出来的python程序不一定是完全正确的。即使所有逻辑都对了,但是用户在使用过程的不当,也会导致程序运行出错。
  本文结构:

  •   常见的异常类型
  •   如何处理异常
  •   如何自定义异常
  1. 常见的异常大概有以下的一些:

  •   NameError         尝试访问一个没有声明的变量
  如图,在f() 函数里,试图打印一个未被定义的变量yy,当调用f()函数时,将会抛出一个NameError 的异常。
DSC0000.png


  •   ImportError        无法引入模块或包;可能路径不存在
  如图,试图import 模块abc12,但是由于abc12 并不是已经被定义了的模块,所以程序就会抛出ImportError 的异常。
DSC0001.png


  •   IndentationError     语法错误(的子类);代码没有正确对齐
  如图1,如果空格键和Tab键混用,也是会抛出IndentationError 这个语法错误。a前用了空格键,b前用了tab键。
  如图2,就是明显的没有对齐了,语法错误。
DSC0002.png

DSC0003.png


  •   SyntaxError        语法错误


  •   IndexError         索引超出序列范围
  如图,访问列表时,访问了超出索引范围,就会抛出IndexError 异常
DSC0004.png


  •   KeyError          请求一个不存在的字典关键字
  如图,对字典dic 的访问,使用了一个不存在的key值,就会抛出KeyError异常
DSC0005.png


  •   IOError           输入输出错误(比如要读的文件不存在)
  如图,用open() 函数尝试打开一个不存在的文件,则会抛出IOError异常。但是如果是使用‘w’的方式打开,则不存在的文件会被创建。
DSC0006.png


  •   AttributeError      访问未知对象属性


  •   ValueError         传给函数的参数类型不正确,比如int()函数传入字符串函数
  如图,给int()函数传入一个非数字的字符参数,会抛出ValueError 异常
DSC0007.png


  •   UnboundLocalError    试图访问一个还未被设置的局部变量
  如图,变量y 在函数f()外面已经被定义,但是在f()方法里,它是一个局部变量,y还没使用,不能直接对其进行赋值操作。
  但是,在第二个f()函数的定义中,直接print 打印y值,这样做是不会抛出异常的。
DSC0008.png


  •   KeyboardInterrupt    键盘中断异常,例如ctrl+c
  time.sleep(60)  让程序休眠60秒,在休眠的过程中,按下ctrl+c,将会终端time.sleep()进程,同时抛出KeyboardInterrupt异常。
DSC0009.png

  2. 如何处理异常
  在python中处理异常,需要对异常捕获,再处理。在python中捕获异常的代码大概是这样的:
try:  
    try_suite
  
except Exception1,Exception2,...,Argument:
  
    exception_suite
  
    #other exception block
  
else:
  
    no_exceptions_detected_suite
  
finally:
  
    always_execute_suite
  如上,在try 里捕获异常,如果try_suite 抛出了异常,那么异常就会被捕获。
  然后except 对捕获的异常类型进行判断,如果是想要捕获的异常类型,则在excepttion_suite 里做一些处理。
  Exception1, Exception2 是Exception 异常类型对象,例如在文章第一部分列出的常见异常类型NameError,IndexError等异常类型。
  Argument
  else 语句,是当try 没有捕获到任何异常时,就会执行no_exception_detected_suite 里的操作。但是,else 部分并不是必须的,它可以被省略。即使省略了else 部分,甚至将except 部分也省略了,也是可以的。只要有try 部分就可以对异常进行捕获了。
  finally 语句,无论是否捕获到异常,异常处理是否被执行了,都一定会将finally部分执行的。所以,通常会将,文件关闭,资源回收这些操作放在finally部分执行。finally 部分也是可以省略的。
  2.1 try...except... 结构
  大概的结构:
try:  
    try_suite
  
except Exception:
  
    except_suite
  只要try_suite 抛出异常,可能会被try 语句捕获,try 捕获后,就会将异常交给except 语句处理,如果异常是except 需要判定的Exception 则,执行except_suite 的语句。
  例子:
DSC00010.png

  如上图,try 捕获到ZeroDivisionError, 通过Except 判定是需要捕获的,则执行print 输出代码块。
  try...except... 可以一次捕获多个错误,可以将异常写在同一个except 里,也可以分开在多个except 语句,例如:
DSC00011.png

  如上图,分别用两个except 语句处理了try语句捕获到的ZeroDivisionError 和ValueError 的异常。
  如果不知道需要捕获什么异常,except 可以什么异常类型都不带。例如:
DSC00012.png

  如图,两个函数里的try...except... 语句块里的except 都没有带具体的Exception类型,所以只要在try 语句里捕获到的任何异常,交给except 语句都会执行except_suite 语句。
  当然,除了将多个异常写在不同的except 语句里,也可以将多个异常类型写在一个except 里,例如:
try :  
    try_suite
  
except  Exception1, Exception2,...:
  
    except_suite
  except 语句除了能捕获异常类型外,还可以创建异常类型的实例,通过异常的实例可以 知道有关异常的更多信息,这对我们跟踪和处理异常是很有帮助的。异常的实例,就是except Exception1,Exception2,...,Argument里的Argument参数了。Exception1,Exception2等都是异常的类型,如果try 捕获到的异常,是except 需要判定的,那么Argument 就会被except 创建为该类型的实例。通过实例,可以知道更多的异常信息。例如:
DSC00013.png 如图,try 捕获了一个除零异常,并且创建了一个异常类型的实例Argument。

  通过打印Argume 的信息,可以更具体地知道异常的信息。
  2.2 try...except...else...
try:  
    try_suite
  
except Exceptions1,...argument:
  
    except_suite
  
else:
  
    other_suite
  try...except... 就不用多说了。else类似于if...elsse... 结构的else.当try 没有捕获到异常,那么else 语句中的other_suite 语句将会执行。
DSC00014.png

  如上图,第一次打开当前路径存在的文件,没有异常抛出,则执行了except 的语句。第二次,尝试打开一个当前路径不存在的文件,则抛出了IOError 的异常。
  2.3 finally...子句
  finally 语句,无论有没有异常被捕获,它都会执行。可以try和finally 配合使用,也可以和except 和else一起配合使用。
  例如:
try:  
    fd = open('/home/hell/hell.txt')
  
except IOError, re:
  
    print "Error: no such  file"
  
else:
  
    print "cool~"
  
finally:
  
    print "end..."
  3. 自定义异常
  通过自定义异常类,但是这个类需要继承父类Exception 异常类.
DSC00015.png

  (1) 定义了一个继承自Exception 的自定义异常类FunError ,类里的__str__()方法被定义为return 一条信息,通常作为异常信息。
  (2) 定义一个f() 函数,在函数里抛出异常,使用关键字raise。raise 关键字可以用来抛出一个异常。
  (3) 所以,如果调用f() 函数,那么函数就会抛出一个FunError()的异常类。
  (4) 当抛出FunError() 异常类时,异常类的实例同时被创建,那么类的__str__() 方法就会被调用,所以,就可以看到异常信息FunError: I am a func Error.
  所以,自定义的FunError 类,也是可以被try 来捕获的,例如:
DSC00016.png

  如图,在try 里调用f() 函数,它会抛出异常,被except 捕获,将异常类的实例e 打印,打印的就是类的__str__() 方法的信息。

运维网声明 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-546973-1-1.html 上篇帖子: 用Python实现随机验证码 下篇帖子: python 替换文件中的字符
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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