zoukankan      html  css  js  c++  java
  • 16.python异常处理

    Python 有两种错误很容易辨认:语法错误和异常(本文将重点介绍python的异常)。

    python语法错误:

    Python 的语法错误或者称之为解析错,是初学者经常碰到的;

    >>>while True print('Hello world')
      File "<stdin>", line 1, in ?
        while True print('Hello world')
                       ^
    SyntaxError: invalid syntax

    函数 print() 被检查到有错误,是它前面缺少了一个冒号 :语法分析器指出了出错的一行,并且在最先找到的错误的位置标记了一个小小的箭头。

    python异常:

    即便 Python 程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行;一般情况下,在Python无法正常处理程序时就会发生一个异常;异常是Python对象,表示一个错误;当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。

    >>>10 * (1/0)                         # 0 不能作为除数,触发异常
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ZeroDivisionError: division by zero
    >>> 4 + spam*3 # spam 未定义,触发异常 Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: name 'spam' is not defined
    >>> '2' + 2 # int 不能与 str 相加,触发异常 Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: Can't convert 'int' object to str implicitly

    异常以不同的类型出现,这些类型都作为信息的一部分打印出来: 例子中的类型有 ZeroDivisionError,NameError 和 TypeError。错误信息的前面部分显示了异常发生的上下文,并以调用栈的形式显示具体信息。

    python异常的处理:

    python提供了两个非常重要的功能来处理python程序在运行中出现的异常和错误。你可以使用该功能来调试python程序。异常处理断言(Assertions)

    异常处理涉及的5个关键字:

    try理解它是扫描器,将可能出现异常的代码放入其中;如果在执行的过程中出现异常对象了,扫描器会立即察觉到此异常对象,但是它没有处理它的能力,所以会将异常对象给到except(捕获器)进行处理。

    except理解它是捕获器,后面可以定义异常类型,并且和as关键字配合使用;定义多个except是合法的,但是它的执行顺序是有由上往下,一旦匹配上某个except,之后的就不执行了;匹配成功就理解将异常对象捕获住并且kill,顺便会执行except内部的代码。(注意:except不能捕获处理类似于语法错误这种情况)

    finally将一定需要被执行的代码定义其中,【记住】:finally一定会被执行(核心);使用场景:像关闭文件、断开数据库连接等行为都可以放入到finally中。

    else位置在finally前,except后;效果/作用类似于循环;没有异常对象出现,else就会被执行,反之不会被执行。

    raise手动抛出一个异常类型的对象,定义:raise 异常类型(msg)。

    定义格式:

    格式一:  多个except语句并列存在,每个except包含一种类型,如果它们之间没有子父类的关系(互斥),那么谁上谁下无所谓, 如果它们之间存在子父类的关系(包含),那么小的在上,大的在下。

    try:
            语句块1
    except 异常类型1 as e:
            语句块2                              
    except 异常类型2 as e:
            语句块3              
    except 异常类型3 as e:
            语句块4
    finally:
            语句块5       

    格式二:一个except具备多个捕获能力(捕获多种不同类型异常对象)。

    try:
             语句块1
    except 异常类型1 as e:
             语句块2                              
    except 异常类型2 as e:
             语句块3              
    except 异常类型3 as e:
             语句块4
    except (异常类型4,异常类型5,...,异常类型m) as e:
    finally:
             语句块5                                        

    格式三:Exception是所有异常类型的父类型,它都是定义在最后一个except的位置。         

    try:
            语句块1
    except 异常类型1 as e:
            语句块2                              
    except 异常类型2 as e:
            语句块3              
    except 异常类型3 as e:
            语句块4
    except (异常类型4,异常类型5,...,异常类型m) as e:
            语句块5
    except Exception as e:
            语句块6
    finally:
                  语句块7

                    

    格式四: 【Exception的简化版使用】:如果定义了except,那么它必须是最后一个except,它可以理解为是Exception的简化形式         

    try:
            语句块1
    except 异常类型1 as e:
            语句块2                              
    except 异常类型2 as e:
            语句块3              
    except 异常类型3 as e:
            语句块4
    except (异常类型4,异常类型5,...,异常类型m) as e:
            语句块5
    except:
            语句块6
    finally:
            语句块7              

                

     代码演示自动抛出异常对象:

     2 
     3 def div(a,b):
     4     print(a / b)
     5 
     6 div(10,0)
     7 
     8 # 演示异常处理的方式一:try ... except ...
     9 try:
    10      print(10/0)
    11 except ZeroDivisionError as e:
    12      print(e)
    13 
    14 try:
    15     print("abc"+123)
    16 except TypeError as e:
    17     print(e)
    18 
    19 try:
    20     print(a)
    21 except NameError as e:
    22     print(e)
    23 
    24 try:
    25     lt = [1,2,3,4,5]
    26     print(lt[5])
    27 except IndexError as e:
    28     print(e)
    29 
    30 try:
    31     fr = open(r'C:UsersAdministratorDesktopkaifanglist1.txt','r',encoding='utf-8')
    32     print(fr.read())
    33     fr.close()
    34 except FileNotFoundError as e:
    35     print(e)
    36 
    37 except(ZeroDivisionError,TypeError,NameError,IndexError,FileNotFoundError) as e:
    38      print('我能捕获5种类型的异常对象...')
    39  
    40 except Exception as e:
    41      print('我是所有异常类型的父类型,我能解决所有的异常类型对象...')
    42  
    43 except:
    44     print('我是Exception的简化形式,我只能出现在最后一个except的位置...')

    代码演示finally语句的使用:将一定要被执行的代码定义在finally中,不管之前的代码怎么样(异常是否被解决),finally一定会被执行,在后期的学习和开发中,我们将关闭文件、关闭数据库连接等操作都定finally中。

     1 try:
     2      fr = open(r'C:UsersAdministratorDesktopa.txt','r')       # 文件能打开
     3      print(fr.read())
     4      print(10 / 0)
     5      # fr.close()        # 因为关闭文件操作是一定要被执行的 但是在try里面也有可能存在风险性,当print(10 / 0)行不了,则无法执行close操作,所以关闭文件需要放在finally语句当中
    6 except: 7 print('解决异常') 8 finally: 9 print('我是finally,我一定会被执行...') 10 fr.close() 11 12 13 # 但是如果一开始就是一个打不开的文件,则也没有办法关闭文件 14 fr = 0 15 try: 16 fr = open(r'C:UsersAdministratorDesktopa111.txt','r') # 没有此文件名 (文件存在则fr不为None值) 17 print(fr.read()) 18 except: 19 print('解决异常') 20 finally: 21 print('我是finally,我一定会被执行...') 22 if fr: # fr为None值则if为False,否则为True,执行以下指令(为了安全性) 23 fr.close()

    finally案例演示二(进一步理解):

     1 # Finally案例:分别输出了哪些内容,返回值是多少
     2 
     3 def func():
     4     try:
     5         print('我是try...')
     6         print(10 / 2)
     7         return 1       #执行此步 则函数就结束了,又因为finally一定要被执行,所以return 1不会被执行,直接调到finally
     8     except:
     9         print('我是except...')
    10         return 2
    11     finally:
    12         print('我是finally...')
    13         return 3
    14 
    15 num = func()
    16 print(num)
    17 '''结果得到是       
    18 我是try...
    19 5.0
    20 我是finally...
    21 3'''
    22 
    23 # 如果题目改为如下,则
    24 def func():
    25     try:
    26         print('我是try...')
    27         print(10 / 0)
    28         return 1
    29     except:
    30         print('我是except...')
    31         return 2     #执行此步 则函数就结束了,又因为finally一定要被执行,所以return 2不会被执行,直接调到finally
    32     finally:
    33         print('我是finally...')
    34         return 3
    35 
    36 num = func()
    37 print(num)
    38 '''结果得到是       
    39 我是try...
    40 我是except...
    41 我是finally...
    42 3'''
    43

    【补充】with open...操作:不需要程序员人为的去书写 close() 函数

    1 With open(r'C:UsersAdministratorDesktopa.txt','r')as fr:
    2     print(fr.read())

    解决异常也是一样:

    1 try:
    2     with open(r'C:UsersAdministratorDesktopa.txt','r') as fr:
    3         print(fr.read())
    4 except:
    5     print('解决异常...')

    代码演示else语句和异常处理机制配合使用:如果try中没有出现异常对象,那么else语句就一定会被执行,如果try中出现了异常对象,就算被处理了,else还是不会被执行。

     1 try:
     2     print('我是try...')
     3     print(10 / 0)  
     4 except Exception as e:
     5     print('我是except...')
     6 else:
     7     print('我是else...')
     8 finally:
     9     print('我是finally...')
    10 #得到 11 我是try... 12 我是except... 13 我是finally... 14 15 #如果把print(10 / 0) 改为print(10 / 2) 16 17 #得到 18 我是try... 19 5.0 20 我是else... 21 我是finally...


    代码演示raise的使用:(手动抛出异常对象)

     1 age = 18 
     2 if age < 0 or age > 130:
     3      try:         
     4           raise Exception('年龄有问题...')     
     5      except:         
     6           print('年龄不合法...正在处理')         
     7           pass 
     8 else:     
     9      print('年龄为:%d' %age)
    10 print('能走吗?')
    11 
    12 #得到结果为     
    13 年龄为:18
    14 能走吗?
    15 
    16 #如果第一行是age=-18
    17 #得到结果为     
    18 年龄不合法...正在处理
    19 能走吗?
     1 # 演示异常处理的方式二:不断往上级传递异常对象,回避问题的方式
     2 
     3 def m1():
     4     print('我是m1...')
     5     print(10 / 0)
     6 
     7 def m2():
     8     print('我是m2...')
     9     # try:
    10     m1()
    11     # except:
    12     #     pass
    13 
    14 def m3():
    15     print('我是m3...')
    16     try:
    17         m2()
    18     except:
    19         pass
    20 
    21 m3()
    22 #得到结果  
    23 我是m3...
    24 我是m2...
    25 我是m1...

    python标准异常总结:

    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 用户代码生成的警告

    注意事项】:

    1).try...finally这种格式是合法的,但是它丧失了解决异常对象的能力(所以不会使用)

    2).else语句必须配合except使用,出现位置一定是在最后一个except的后面

    3).常见的运行时异常类型:ZeroDivisionError:分母为0的异常;TypeError:类型有误的异常; NameError:没有定义就使用的异常;IndexError:下标越界的异;FileNotFoundError:文件找不到的异常;...

    4).with open ... as ...语句可以优化原始的open操作!体现:它不需要手动close()文件对象

    总结:学习异常对象简单归纳为5个关键字:try except finally else raise

    python的assert(断言):

    Python的assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况,例如我们的代码只能在 Linux 系统下运行,可以先判断当前系统是否符合条件。

    语法格式如下:assert expression

    等价于:

    if not expression:

            raise AssertionError

    assert 后面也可以紧跟参数: assert expression [, arguments]

    等价于:

    if not expression:

            raise AssertionError(arguments)

    代码演示assert示例:

     1 >>> assert True     # 条件为 true 正常执行
     2 >>> assert False    # 条件为 false 触发异常
     3 Traceback (most recent call last):
     4   File "<stdin>", line 1, in <module>
     5 AssertionError
     6 
     7 >>> assert 1==1    # 条件为 true 正常执行
     8 >>> assert 1==2    # 条件为 false 触发异常
     9 Traceback (most recent call last):
    10   File "<stdin>", line 1, in <module>
    11 AssertionError
    12 
    13 >>> assert 1==2, '1 不等于 2'
    14 Traceback (most recent call last):
    15   File "<stdin>", line 1, in <module>
    16 AssertionError: 1 不等于 2
    17 
    18 
    19 # 判断当前系统是否为 Linux,如果不满足条件则直接触发异常,不必执行接下来的代码:
    20 import sys
    21 assert ('linux' in sys.platform), "该代码只能在 Linux 下执行"
    22 # 接下来要执行的代码
  • 相关阅读:
    DYCom多平台聊天室Sample
    silverlight多人在线游戏示例
    设计模式之: 命令模式
    Vector
    flashBuilder加入AsDoc注释
    转:每个Flash开发者应该知道的事情
    flashBuilder无法调试:57%就不动了
    UML类图实例
    Dictionary
    Enterprise Architect使用(一)
  • 原文地址:https://www.cnblogs.com/bonheur/p/12374383.html
Copyright © 2011-2022 走看看