zoukankan      html  css  js  c++  java
  • 13.python错误和异常

    一.错误和异常
    1.错误(Error):程序中的错误分为俩种
    第一种语法错误:不按照语言的规则,必须在程序执行前就改正
    第二种逻辑错误:算法写错了,加法写成了减法,函数或类使用错误,其实这也属于逻辑错误
    2.异常(Exception):就是程序运行时发生错误的信号,本身就是意外情况,这有个前提,没有出现上面说的错误,也就是说程序写的没有问题,但是在某些情况下,会出现一些意外,导致程序无法正常的执行下去。
    (1)例如open函数操作一个文件,文件不存在,或者创建一个文件时已经存在了,或者访问一个网络文件,突然断网了,这就是异常,是个意外的情况,异常不可能避免。
    (2)分为三部分
    ①Traceback:异常追踪的信息
    ②NameError:
    ③NameError异常类后面的是:异常值
    3.错误和异常:在高级编程语言中,一般都有错误和异常的概念,异常是可以捕获,并被处理的,但是错误是不能被捕获的
    (1)异常

    with open('testabc') as f:
        pass
    
    ##异常
    Traceback (most recent call last):
      File "test2.py", line 1, in <module>
        with open('testabc') as f:
    FileNotFoundError: [Errno 2] No such file or directory: 'testabc'

    (2)错误

    def 0A():
        pass
    
    ##错误:
        def 0A():
            ^
    SyntaxError: invalid syntax

    总结:一个健壮的程序,尽可能的避免错误,尽可能的捕获,处理各种异常
    4.python中的常用的异常种类
    在python中不同的异常可以用不同的类型(python中统一了类与类型,类型即类)去标识,不同的类对象标识不同的异常,一个异常标识一种错误
    AttributeError:视图访问一个对象没有属性,比如foo.x,但是foo没有属性x
    IOError:输入/输出操作失败(基本上是无法打开文件)
    TypeError:传入对象类型与要求的不符合
    ValueError 传入一个调用者不期望的值,即使值的类型是正确的
    5.异常类及继承层次
    python异常的继承

    BaseException[所有内建异常类的基类]
    +--SystemExit[sys.exit()函数引发的异常,异常不捕获处理,就直接交给python解释器,解释器退出]
    +--KeyboardInterrupt[对应的捕获用户中断行为Ctrl+c]
    +--GeneratorExit
    +--Exception[是所有内建的,非系统退出的异常的基类,自定义异常应该继承自它]
        +--自定义异常[从Exception继承的类]
        +--RuntimeError
            +RecursionError
        +--MemoryError
        +--NameError[异常类(错误的类型)]
        +--StopIteration
        +--StopAsyncIteration
        +--ArithmeticError[所有算术计算引发的异常,其子类的除零异常等]
            +--FloatingPointError
            +--OverflowError
            +--ZeroDivisionError
        +--LookupError[使用映射的键或序列的索引无效时引发的异常的基类:IndexError,KeyError]
            +--IndexError
            +--KeyError
        +--SyntaxError[语法错误:Python将这种错误也归到异常类下面的Exception下的子类,但是这种错误是不可捕获的]
        +--OSError
            +--BlockingIOError
            +--ChildProcessError
            +--ConnectionError
                +--BrokenPipeError
                +--ConnectionAbortedError
                +--ConnectionRefusedError
                +--ConnectionResetError
            +--FileExistsError
            +--FileNotFoundError
            +--InterruptedError
            +--InterruptedError
            +--IsADirectoryError
            +--NotADirectoryError
            +--PermissionError
            +--PermissionError
            +--ProcessLookupError
            +--TimeoutError

    6.异常处理
    (1)异常处理:把产生的异常捕捉到,进入另外一个处理分支,执行你为其制定的逻辑,使程序不会崩溃,这就是异常处理
    (2)为何要进行异常处理:当触发异常后且没有被处理的情况下,程序就在当前异常终止,后面的代码不会运行,所以必须提供一种异常处理机制来增强你的程序健壮性与容错性
    (3)异常是由程序的错误引起的,语法上的错误跟异常处理无关,必须在程序运行前就修正
    二.异常处理
    方式一:if处理异常

    #第一段代码
    age=input('>>: ')
    if age.isdigit():
         int(age)                  #主逻辑:如果用户输入是数字才会运行主逻辑
    
    elif age.isspace():            #如果用户输入空格
         print('用户输入的空格')
    elif len(age) == 0:            #如果用户输入空
         print('用户输入的为空')
    else:                          #如果用户输入除数字其它
         print('其他的非法输入')
        
    #第二段代码
    num2=input('>>: ')             
    if num2.isdigit():
         int(num2)                 #主逻辑
    elif num2.isspace():
         print('---->用户输入的空格')
    elif len(num2) == 0:
         print('----》用户输入的为空')
    else:
         print('其他的非法输入')

    总结:
    (1)if做异常处理只能针对一段代码,对于不同的代码段的相同类型的错误你需要重复的if来进行处理。
    (2)在你的程序中频繁的写与程序本身无关,与异常处理有关的if
    方式二:try...except:python为每一种异常定制了一个类型,然后提供一种特定的语法结构用来进行异常处理
    1.基本语法:

    try:
        被检测的代码块
    except [异常类型]:
        异常的处理代码块      #try中一旦检测到异常,就执行这个位置的逻辑

    举例:

    try:
        #产生异常
        1/0
        #产生异常后下面不执行
        print('after')
    #交给except处理
    except:
        print('exception')    #打印结果:exception

    总结:
    上例子执行到1/0时产生异常并抛出,由于使用了try...except语句块则捕捉到了这个异常,异常生成位置之后语句将不再执行,转而执行对应的except部分的语句,最后执行try...except语句块之外的语句。
    使用try..except的方式的好处:
    ①把错误处理和真正的工作分开
    ②代码更易组织,更清晰,复杂的工作任务更容易实现
    ③更安全,不至于由一些小的疏忽而使程序意外崩溃了
    2.as子句:

    try:
        #主逻辑1输出整型
        age=input('1>>: ')
        int(age)
    
        #主逻辑2输出整型
        num2=input('2>>: ')
        int(num2)
    
    #except捕捉ValueError俩段代码同一种异常把取名字为e
    except ValueError as e:
        #在哪个位置引发异常异常会被except捕捉到,如果能捕捉到就会执行except以下的代码,直接打印捕捉的异常错误,如果捕捉不到程序蹦掉
        print(e)

    主逻辑1当输入123时候是整型没报错继续往下执行
    1>>: 123
    主逻辑2输入abc不是整型抛出异常被except捕捉到
    2>>: abc
    打印捕捉到的错误:invalid literal for int() with base 10: 'abc'
    3.异常的捕获:except可以捕获多个异常
    (1)如果你想要的效果是,无论出现什么异常,我们统一丢弃,或者使用同一段代码逻辑去处理他们,只有一个Exception万能异常就足够了
    (2)如果你想要的效果是,对于不同的异常我们需要定制不同的处理逻辑,那就需要用到多分支

    s1 = 'xixi'
    #s1=1
    try:
        int(s1)
    #多分支异常1
    except IndexError as e:
        print(e)
    
    #多分支异常2
    except KeyError as e:
        print(e)
    
    #多分支异常3:捕获到异常
    except ValueError as e:
        print(e)                #捕获到异常打印:invalid literal for int() with base 10: 'xixi'
    
    #多分支万能异常其他没有考虑到的
    except Exception as e:
        print(e)        

    捕获规则总结:
    ①捕获是从上到下依次比较,如果匹配,则执行匹配的except语句块
    ②如果被一个except语句捕获,其他except语句就不会再次捕获了
    ③如果没有任何一个except语句捕获到这个异常,则该异常向外抛出    
    捕获的原则:
    ①从小到大,从具体到宽泛
    4.主动触发异常(raise)
    (1)raise后什么都没有,表示抛出最近一个被激活的异常,入股没有被激活的异常,则抛类型异常。
    (2)raise后要求应该是BaseException类的子类或实例,如果是类,将被无参实例化。

    try:
        #python提供一堆类型就是类,类加上括号进行实例化,raise可以TypeError加一个括号传值进去
        raise TypeError('类型错误')  
    except Exception as xi:
        print(xi)                      #打印结果:类型错误

    5.自定义异常类:

    #自定义异常就是在写一个类,这个类就是XiXiException这个异常,自定义异常必须继承Exception这个类
    class XiXiException(Exception):
        pass
    
    #主动触发异常用raise触发
    try:
        #raise主动触发自定制的异常类XiXiException实例化产生的异常对象
        raise XiXiException('自定制异常')
    
    #except捕捉到这个异常
    except XiXiException as xixi:
        print(xixi)                         #打印结果:自定制异常

    6.异常的捕获时机
    (1)立即捕获:需要立即返回一个明确的结果

    def parse_int(s):
        try:
            return int(s)
        #立即捕获异常
        except:
            #返回异常结果
            return 0
        
    #正常传整数调用函数:
    print(parse_int(123))     #返回结果:123
    #不正常传字符串调用函数捕捉异常
    print(parse_int('a'))     #返回结果:0

    (2)边界捕获:封装产生了边界
    例如,写一个模块,用户调用这个模块的时候捕获异常,模块内部不需要捕获,处理异常,一旦内部处理了,外部调用者就无法感知了,
    例如,open函数,出现的异常交给调用者处理,文件存在了,就不用再创建了,看是否修改还是删除
    例如,自己写一个类,使用open函数,但是出现了异常不知道如何处理,就继续向外层抛出,一般来说最外层也就是边界,必须处理这个异常了,否则线程退出  
    7.其他的异常结构(else和finally)
    语法:

        try:
            <语句>   #运行别的代码
        except <异常类><语句>   #捕获某种类型的异常
        except <异常类> as <变量名><语句>   #捕获某种类型的异常并获得对象
        else:
            <语句>   #如果没有异常发生
        finally:
            <语句>   #退出try时总会执行

    举例:

    s1 = 'xixi'
    #s1=1
    try:
        int(s1)
    except IndexError as e:  #多分支异常1
        print(e)
    except KeyError as e:    #多分支异常2
        print(e)
    except ValueError as e:  #多分支异常3
        print(e)
    except Exception as e:   #多分支万能异常其他没有考虑到的
       print(e)
    else:            #try内代码里没有异常的情况下会执行else里的东西
        print('try内代码块没有异常执行')
    finally:         #无论异常与否都会执行finally里的东西,通常是清理工作
        print('try内代码块有没有异常,都会执行')
    
    print(11111111111)
    print(22222222222)
    print(33333333333)
    
    ####打印结果:
    invalid literal for int() with base 10: 'xixi'
    try内代码块有没有异常,都会执行
    11111111111
    22222222222
    33333333333    

    8.try的工作原理:
    (1)如果try中语句执行时发生异常,搜索except子句,并执行第一个匹配该异常的except子句
    (2)如果try中语句执行时发生异常,却没有匹配的except子句,异常将被递交到外层的try,如果外层不处理这个异常,异常将继续向外层传递。如果都不处理该异常,则会传递到最外层,如果还没有处理,就终止异常所在的线程
    (3)如果在try执行时没有发生异常,将执行else子句中的语句
    (4)无论try中是否发生异常,finally子句最终都会执行
    9.断言assert:在程序的某个位置判断一下结果是否是你想要的值,如果不是想要的值抛出异常

    def test():       #定义test函数
        '一堆逻辑'
        res=1         #由一堆逻辑处理完得到一个结果是1
        return 1     #处理完逻辑返回一个值1
    res1=test()       #一堆逻辑运行得到一个结果赋值给res1
    
    assert res1 == 1   #断言判断res1是否等于1
    
    #下面的代码,要跟res1的结果进行下一步处理  

    三.未实现和未实现异常

    #未实现
    print(NotImplemented)           #打印结果:NotImplemented
    
    #未实现异常
    print(NotImplementedError)      #打印结果:<class 'NotImplementedError'>

    总结:
    NotImplemented是个值,单值,是NotImplementedType类的实例
    NotImplementedError是类型,是异常,返回type

  • 相关阅读:
    linux下XAMP集成开发环境搭建流程总结
    一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10 http://www.jb51.net/css/383986.html
    安装软件时出现错误提示:无效类
    新建.xlxs文件打不开,旧的可以打开的解决办法
    PostgreSQL 自定义自动类型转换(CAST) 删除用 drop function integer_to_text(integer) CASCADE;
    php扩展不能加载的原因
    remote_addr(::1)不返回IPv4地址127.0.0.1的解决办法
    php转换字符串编码 iconv与mb_convert_encoding的区别
    PHPExcel获取CSV文件数据不准确,用以下方法获取
    日文SJIS编码字符串字符数获取方法
  • 原文地址:https://www.cnblogs.com/xixi18/p/9908042.html
Copyright © 2011-2022 走看看