zoukankan      html  css  js  c++  java
  • Python中异常处理

    1、异常 Exception

    错误Error

    逻辑错误:算法写错了,加法写成了减法。

    笔误:变量名写错了,语法错误。

    错误可以避免的

    异常Exception

    本身就是意外情况。一些意外,导致程序无法正常的执行下去。

    是不可避免的。

    错误和异常

    在高级编程语言中,一般都有错误和异常的概念,异常是可以捕获的并被处理的,但是错误是不能捕获的。

    with open('test') as f:
        pass

    错误信息:

    Traceback (most recent call last):

      File "C:/Users/WCL/PycharmProjects/untitled1/package/test1/异常处理.py", line 1, in <module>

        with open('test') as f:

    FileNotFoundError: [Errno 2] No such file or directory: 'test'

    def 0A():
        pass

      File "C:/Users/WCL/PycharmProjects/untitled1/package/test1/参数检查.py", line 142

        class typeassert

                       ^

    SyntaxError: invalid syntax

    一个健壮的程序,尽可能的避免错误。

    尽可能的捕获,处理各种异常。

    2、产生异常

    产生:raise语句显示的抛出异常。

    Python解释器自己检测到异常并引发他。

    def foo():
        print('-----')
        def bar():
            print(1/0)
        bar()
        print('after')
    foo()

    def bar():
        print('+++++++++++++')
        raise Exception('Exc')
        print('+-+-+-+-+-+')
    bar()

    程序会在异常抛出的地方中断执行,如果不进行捕获,就会提前结束程序。

    raise语句

    raise后什么都没有,表示抛出最近一个被激活的异常,如果没有被激活的异常,则抛出类型异常。很少利用的方式。

    raise

    后要求应该是BaseException类的子类或实例,如果是类,将被无参实例化。

    异常必须出自BaseException

    sys.exc_info()查看异常所在的元素。

    sys.exc_info() ,后面是个元组。(异常类、异常对象,trackback)

    3、异常捕获

    try:

      待捕获异常的代码块  

    except[异常类型]:

    异常的处理代码块

    try:
        print('++++++++++++++++')
        c = 1/0
        print('----------------')
    except:
        print('catch the exception')
    print('outer')

    ++++++++++++++++

    catch the exception

    Outer

    执行到c = 1/0时候产生异常并抛出,由于使用了语句捕捉这个异常,所以产生异常位置后面的语句将不再执行了,转而执行对象except以外的语句。

    2)捕获指定类型的异常。

    try:
        print('++++++++++++++++')
        c = 1/0
        print('----------------')
    except ArithmeticError:
        print('catch the ArithmeticError:')
    print('outer')

    ++++++++++++++++

    catch the ArithmeticError:

    Outer

    特别关心的异常放在最上面。

    自己定义的异常。

    Exception 非退出性异常。

    捕获原则:

    4、异常类即继承层次

    def exc_hierarchy(exc=BaseException, level=-1):
        name = exc.__name__
        if level == -1:
            print(name)
        else:
            print("{} +-- {}".format('    ' * level, name))
        for sub in exc.__subclasses__():
            exc_hierarchy(sub, level+1)

    BaseException

     +-- Exception

         +-- StopAsyncIteration

         +-- OSError

             +-- BlockingIOError

             +-- FileNotFoundError

             +-- IsADirectoryError

             +-- TimeoutError

             +-- InterruptedError

             +-- ProcessLookupError

             +-- NotADirectoryError

             +-- ConnectionError

                 +-- BrokenPipeError

                 +-- ConnectionAbortedError

                 +-- ConnectionRefusedError

                 +-- ConnectionResetError

             +-- UnsupportedOperation

             +-- FileExistsError

             +-- ChildProcessError

             +-- PermissionError

         +-- ArithmeticError

             +-- FloatingPointError

             +-- OverflowError

             +-- ZeroDivisionError

         +-- AttributeError

         +-- SyntaxError

             +-- IndentationError

                 +-- TabError

         +-- SystemError

             +-- CodecRegistryError

         +-- ImportError

             +-- ZipImportError

         +-- BufferError

         +-- LookupError

             +-- IndexError

             +-- KeyError

             +-- CodecRegistryError

         +-- NameError

             +-- UnboundLocalError

         +-- TypeError

         +-- error

         +-- StopIteration

         +-- AssertionError

         +-- Warning

             +-- UserWarning

             +-- DeprecationWarning

             +-- UnicodeWarning

             +-- PendingDeprecationWarning

             +-- ImportWarning

             +-- RuntimeWarning

             +-- ResourceWarning

             +-- SyntaxWarning

             +-- BytesWarning

             +-- FutureWarning

         +-- Error

         +-- ValueError

             +-- UnicodeError

                 +-- UnicodeEncodeError

                 +-- UnicodeDecodeError

                 +-- UnicodeTranslateError

             +-- UnsupportedOperation

         +-- ReferenceError

         +-- RuntimeError

             +-- RecursionError

             +-- NotImplementedError

             +-- _DeadlockError

         +-- MemoryError

         +-- EOFError

     +-- GeneratorExit

     +-- KeyboardInterrupt

     +-- SystemExit

    5、BaseException及子类

    1)BaseException所有内建异常类的基类是BaseException。

    2)SystemExit

    sys.exit()函数引发的异常,异常不捕获处理,就直接交给Python解释器,解释器退出。

    import sys
    print('++++')
    sys.exit(1)
    print('sysexit')
    print('-----')

    ++++

    Process finished with exit code 1

    未进行捕获的情况下,

    解释器直接退出了。

    import sys
    try:
        print('++++')
        sys.exit(1)
    except SystemExit:
        print('sysexit')
    print('-----')

    ++++

    sysexit

    -----

    捕获的情况下正常执行,且被捕获。

    3)Keyboardinterrupt

    对应捕获用户中断的行为 Ctrl + c

    6、Exception及子类

    Exception是所有内建的,非系统退出的异常的基类,自定义异常应该定义继承自它。

    1)SyntaxError语法错误,Python中也归到Exception类中,但是语法错误是不可被捕获的。

    2)ArithmeticError所有算数计算引发的异常,其子类有除零异常等。

    3)LookupError 使用映射的键或者序列的索引无效是引发的异常的基类:indexerror keyerror

    4)自定义的异常:从Exception继承的类。

    7、异常的捕获

    Except可以捕获多个异常。

    捕获的原则:捕获是从上到下依次比较,如果匹配,则执行匹配的except语句块。

    如果被一个except语句块捕获,其他的except就不会再次捕获了。

    如果没有任何一个except语句捕获到这个异常,则该异常向外抛出。

    捕获的原则,从小到大,从具体到广泛。

    8、as子句

    被抛出的异常,应该是异常的实例,获得这个对象的话,使用as子句。

    class MyException(Exception):
        def __init__(self,code,message):
            self.code = code
            self.message = message
    try:
        raise MyException
    except MyException as e:
        print(11111111)
        print('{}{}'.format(e.code,e.message))
    except Exception as e:
        print('{}'.format(e))

    __init__() missing 2 required positional arguments: 'code' and 'message'

    raise后面有特定的参数,如果没有的话就是无参形式。

    9、finally 子句

    Finally 最终,即最后都会是要一定执行的。try.....finally不管有没有异常都会执行。

    Finally中一般都是放置资源的清理,释放工作的语句。

    也可以在finally中再次捕获异常。

    10、finally执行时机

    def foo():
        try:
            return 3
        finally:
            print('finally')
        print('---')
    print(foo())

    尽管函数有return返回语句,但是finally语句还是要执行的,最后才返回return语句。

    拿的值是最后一个return。

    11、异常传递

    def foo1():
        return 1/0

    def foo2():
        print('foo2 ----')
        foo1()
        print('foo2++++')
    foo2()

    foo2调用了foo1,foo1产生的异常传递到了foo2中

    异常总是向外层抛出,如果外层没有处理这个异常,就会继续向外抛出,如果内层捕获并处理了异常,外部就不能捕获的到了。

    如果到了最外层还是没有被处理,就会中断异常所在的线程的执行。

    import threading
    import time

    def foo1():
        return 1/0

    def foo2():
        time.sleep(3)
        print('foo2----')
        foo1()
        print('foo2++++')
    t = threading.Thread(target=foo2)
    t.start()

    while True:
        time.sleep(1)
        print('Everything OK')
        if t.is_alive():
            print('live')
        else:
            print('dead')

    未进行捕获异常,异常抛出直接中断了线程。

    sys.exc_info() ,后面是个元组。(异常类、异常对象,trackback)

    12、try 的嵌套

    try:
        try:
            ret = 1/0
        except KeyError as k:
            print(k)
        else:
            print('ok')
        finally:
            print('finally')
    except:
        print('c ok')
    finally:
        print('fin')

    内部捕获不到异常,会向外层传递异常。

    但是如果内层有且有finally而且其中有return、break语句,否则就不会继续往外抛出异常。

    def foo():
        try:
            ret = 1/0
        except KeyError as F:
            print(k)
        finally:
            print('finally a ')
            return   #异常直接被丢弃
    try:
        foo()
    except:
        print('+++++')
    finally:
        print('-------')

    有return语句,异常直接被丢弃。

    13、异常的捕获时机

    1)立即捕获

    需要立即返回一个明确的结果


    def parse_int(s):
        try:
            return int(s)
        except:
            return 0
    print(parse_int('s'))

    被return直接返回0

    2)边界捕获

    封装产生了边界。

    (1)一个模块,用户调用了这个模块的时候捕获异常,异常内部不需要捕获,处理异常,一旦内部处理了,外部调用者无法感知异常了

    (2)Open函数,出现的异常交给调用者处理,文件存在,就不用创建了,看是否修改修改还是删除。

    (3)自己写了一个类,使用open函数,但是文件出现异常不知道如何处理,就继续向外层抛出,一般来说最外层也是边界,必须处理异常,如果不处理的话,线程就会推出。

    14、else子句

     else子句,没有异常发生,则执行。

    try:
        ret = 1/0
    except ArithmeticError as e:
        print(e)
    else:
        print('ok')
    finally:
        print('fin')
    ####division by zero
    ###fin

    15、总结

     try:

    <语句> #运行别的代码

    except<异常类>:

    <语句>  #捕获某种类型的异常

    except<异常类> as <变量名>:

    <语句>   #捕获某种类型的异常并获得对象

    else:

    <语句> #如果没有异常发生

    finally:

    <语句>  #推出try的时候总会执行

    try的工作原理

    (1)如果try中语句执行时候会发生异常,搜索except子句,并执行第一个匹配该异常的except子句。

    (2)如果try中语句执行时发生异常,却没有匹配except子句,异常将被递交到外层的try,如果外层不处理这个异常,异常将继续向外层传递,如果都不处理该异常,则会传递到最外层,如果还没有处理,就会终止异常所在的线程。

    (3)如果try执行时候没有异常,将执行else子句中的语句。

    (4)无论try中是否发生异常,finally子句最终都会执行。

  • 相关阅读:
    前端安全之XSS攻击
    从JavaScript执行上下文理解变量提升
    em、rem和px的区别
    纯CSS实现幻灯片效果
    小白在使用ISE编写verilog代码综合时犯得错误及我自己的解决办法
    结构体指针中的一点困惑
    xilinx fpga中块ram的使用——简单双端口ram的使用
    在模块中如何去写输出标志位的程序
    学习感悟
    xilinx fpga 生成3*3窗口
  • 原文地址:https://www.cnblogs.com/wangchunli-blogs/p/9949869.html
Copyright © 2011-2022 走看看