• python入门(十一):异常


     1、异常概念:

    >>> a

    Traceback (most recent call last):

      File "<stdin>", line 1, in <module>

    NameError: name 'a' is not defined     #交互模式中,类似这种的便是异常

    2、异常未处理程序终止运行

    当异常出现的时候,且没有做任何处理,程序不会继续执行
    也就是程序被中断了。

    a

    print("ok")

    运行结果:

    E:>python a.py

    Traceback (most recent call last):

      File "a.py", line 1, in <module>

        a                            #出现异常后,且没有做处理,

    NameError: name 'a' is not defined   # a.py的第二行代码并没有被执行

      服务端程序:出现异常没有捕获,程序就中断了
     

    3、异常信息的作用:

    1)指明出错的代码行位置,line xx

    2)异常类型与具体异常说明

    4、异常的影响:

    异常的出现是不好的,未处理异常会中断,程序就退出。

    程序退出了,就不能完成程序预期的功能

       微软曾经统计过,功能性的代码与异常处理的代码数量的比例是1:1

    养成一个习惯:
    1)把异常的信息搞明白什么意思
    2)出错的代码在哪一行,具体的代码是啥。具体分析。
     
     5、为什么会出现异常:
    1) 程序出错了。1/0  变量没定义
    2) 用户输入的数据问题
    def add(a,b)
        return a+b
    a=input("a:")
    b=input("b:")
    hello
    100
    print(add(a,int(b)))
    3) 运行中,性能的问题。内存泄漏、句柄泄露。
     
     6、异常捕获的应用场景:
    1 )可能程序出错的地方
    2 )异常处理用户可能输入的错误数据
    3 )异常处理可能出现的系统(I/O)的错误
    4 )异常处理可能出现的网络的错误
     

    7、写程序的原则

    1)程序不能崩溃

    2)能够提示用户或者程序员明确的信息

     

    8、系统内置的异常信息:

    >>> dir(__builtins__)

    ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']

    9、异常处理模型:

     try:
       result = 1/0  #代码出现异常时,程序会从try跳出来,到except中被拦截,触发
       print("ok")  #except代码块的执行,所以try中的print语句没有被执行
    except:    #except后面没有名字,默认会拦截所有异常
        print("出现一些错误了!")

    print("Done!")
     
     

    ***  try不能单独存在,必须有except或者finally

    ***  try和else也不能单独存在。

    10、使用具体的异常信息拦截

    try:

        result=1/0

        print("ok")

    except ZeroDivisionError:

        print("除0错误")

    except NameError:

        print("变量未定义")

    print("Done")

    运行结果:

    E:>python a.py

    除0错误

    Done

    ------------------------------------------------------

     try:
       s
       print("ok")
    except ZeroDivisionError:
        print("出现除0的操作了!")
    except NameError:
        print("变量没定义!")

    print("Done")

    运行结果:

    E:>python a.py

    变量未定义

    Done

    -------------------------------------------------

    小练习:使用try:except拦截不同的异常,并给出具体的错误信息

    try:

        print(s)                 #try代码块中有两个错误:变量未定义和除0错误

        result=1/0              #变量未定义在前

    except ZeroDivisionError:

        print("除0错误")

    except NameError:

        print("变量未定义")

    print("Done")

    运行结果:

    E:>python a.py

    变量未定义                 #最先输出变量未定义,结束程序

    Done

    #try里面的代码产生的多个异常,只会有一个被抛出,异常信息,只会被拦截一次。便结束程序。

    --------------------------------------------------

    11、缩进错误与语法错误是编译报出来的错误,并不是程序执行时的错误。

    try:

        result=1/0              #除0错误在前

          open("e:\ab.txt")      #缩进错误在后

    except ZeroDivisionError:

        print("除0错误")

    except FileNotFoundError:

        print("文件不存在")

    print("Done")

    运行结果:

    E:>python a.py

      File "a.py", line 3

        open("e:\ab.txt")

        ^

    IndentationError: unexpected indent    #提示缩进错误

    原因为:缩进错误与语法错误是编译器报出来的,此时程序还未执行,故会先报出来!

    ---------------------------------------------------

    12、错误的堆栈

     def a():
        print("a")
        b()

    def b():
        print("b")
        c()

    def c():
        print("c")
        d()

    def d():
        print(1/0)
       

    a()
     

    运行结果;

    E:>python a.py

    a

    b

    c

    Traceback (most recent call last):

      File "a.py", line 17, in <module>   #函数的调用堆栈,将执行过程显示出来。

        a()

      File "a.py", line 3, in a                  #line17-line3-line7-line11-line15显示了调用的先后顺序。

        b()                           

      File "a.py", line 7, in b

        c()

      File "a.py", line 11, in c

        d()

      File "a.py", line 15, in d

        print(1/0)

    ZeroDivisionError: division by zero

    --------------------
     def a():
        print(xx)
        b()

    def b():
        print("b")
        c()

    def c():
        print("c")
        d()

    def d():
        print(1/0)
       

    a()
    --------------------------------------------------- 
    13、默认的except与具体的异常信息共存时:

    try:

        1/0

        print("ok")

    except:                         #未写明具体异常信息的except在前

        print("出现了一些错误")

    except ZeroDivisionError:         #写明具体的异常信息在后

        print("存在除0错误")

    运行结果:

    E:>python a.py

      File "a.py", line 3

        print("ok")

             ^

    SyntaxError: default 'except:' must be last  #运行时提示错误:默认'except:'必须是最后一个,except必须在最后

    14、拦截未拦截住,程序中断

    try:

        print(a)                          #存在a未定义的错误

    except ZeroDivisionError:              #但是异常只有一个除0错误的拦截

        print("存在除0错误")

                                        #也没有except:拦截所有异常的语句

    print("ok")

    运行结果:

    E:>python a.py

    Traceback (most recent call last):

      File "a.py", line 2, in <module>

        print(a)

    NameError: name 'a' is not defined      #输出结果提示:a未定义,但是ok并没有被打印,说明程序未正常执行完毕,出现中断

    解决方法:拦截所有异常

    try:

        print(a)

    except ZeroDivisionError:

        print("存在除0错误")

    except:                             #拦截到所有可能出现的异常

        print("出现未知异常!")           

    print("ok")

    运行结果:

    E:>python a.py

    出现未知异常!

    ok                                 #ok被打印,程序正常执行完毕

              

    15、输出系统提示的错误信息:

    try:

        print(a)

    except NameError as e:           #将系统提示的错误信息作为e保存,变量名不必须是e

        print("变量未定义")          #输出自己定义的错误信息

        print(e)                    #输出系统的提示错误信息

    except :

        print("出现未知异常!")

    print("ok")

    运行结果:

    E:>python a.py

    变量未定义

    name 'a' is not defined              #输出了系统的错误提示信息.但是这个方法没有显示

    ok                               #堆栈信息,不会显示第几行出现了错误

    e是一个对象。查看异常对象中的内容:

    >>>dir(e)

    ['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', 'args', 'with_traceback']

    16、同时显示堆栈信息和报错行数的方法;

    import traceback                 #引入traceback这个包

    try:

        print(a)

    except NameError as e:    

        print("变量未定义")        

        print(e)

        print(traceback.print_exc())    #打印堆栈信息      

    except :

        print("出现未知异常!")

    print("ok")

    运行结果:

    E:>python a.py

    变量未定义                     #自己写的输出的内容

    name 'a' is not defined           #打印的系统提示的错误信息e

    Traceback (most recent call last):   #打印的堆栈信息和报错行数等

      File "a.py", line 4, in <module>

        print(a)

    NameError: name 'a' is not defined

    None                          #traceback.print_exc()的返回值

    ok                             #程序已全部执行完毕

    简化后的代码是:

    import traceback

    try:

        print(a)

    except NameError:    

        print(traceback.print_exc())          

    except :

        print("出现未知异常!")

    print("ok")

    运行结果:

    E:>python a.py

    Traceback (most recent call last):

      File "a.py", line 4, in <module>

        print(a)

    NameError: name 'a' is not defined

    None

    ok

    17、try、else和finally

    1.  else:在try执行完所有内部的代码后,没有异常的情况下才会被执行。有异常,则不会被执行。

    2. finally代码块下的内容,不论try代码块中是否有异常,均会被执行。通常finally都是用于释放资源。

    1)  try中有异常

    try:

        print(a)

    except NameError:    

        print("变量未定义")         

    except :

        print("出现未知异常!")

    else:                              

        print("没有出现异常")

    finally:

        print("无论如何,我都会被执行")

    print("ok")

    运行结果:

    E:>python a.py

    变量未定义                        #try中有异常,else代码块的内容未被执行

    无论如何,我都会被执行            #try中异常,finally被执行

    ok

    2) try中无异常

    try:

        print("gloryroad")

    except NameError:    

        print("变量未定义")         

    except :

        print("出现未知异常!")

    else:

        print("没有出现异常")

    finally:

        print("无论如何,我都会被执行")

    print("ok")

    运行结果:

    E:>python a.py

    gloryroad

    没有出现异常                     #try中无异常,else代码块下的内容被执行

    无论如何,我都会被执行           #try中无异常,finally代码块下的内容被执行

    ok

    18、抛出异常

    1)       抛出异常的位置在实际异常的前面

    import traceback

    try:

        raise ZeroDivisionError         #抛出异常,抛出异常的位置在print(1/0)

        print(1/0)                      #前面,所以会直接排除异常,不会执行下面的

    except NameError:                  #print(1/0)的语句

        print("未知异常")         

    except ZeroDivisionError:

        print(traceback.print_exc())  

    else:

        print("没有出现异常")

    finally:

        print("无论如何,我都会被执行")

    print("ok")

    运行结果:

    E:>python a.py

    Traceback (most recent call last):

      File "a.py", line 3, in <module>

        raise ZeroDivisionError

    ZeroDivisionError

    None                          #输出except ZeroDivisionError下的内容

    无论如何,我都会被执行         #try中有异常,else代码块中的程序未执行,输出finally

    ok                             #中的内容

    2)       抛出异常的位置在实际异常的后面

    import traceback

    try:

        print(a)

        raise ZeroDivisionError

    except NameError:    

        print("未知异常")         

    except ZeroDivisionError:

        print(traceback.print_exc())  

    else:

        print("没有出现异常")

    finally:

        print("无论如何,我都会被执行")

    print("ok")

    运行结果:

    E:>python a.py

    未知异常                         #最先输出实际代码的错误,抛出异常被短路

    无论如何,我都会被执行           #抛出异常的语句未执行

    ok

    3)       抛出异常的应用场景

    满足语法要求,但是不符合业务规则。

    class TooBigException(Exception):   #自定义一个异常

    pass

    num=int(input("请输入一个数字:"))

    try:

        if num>=100:

            raise TooBigException    #当数字大于100时,抛出异常

    except TooBigException:          #抛出异常所打印的内容

        print("输入的数字大于100")         

    else:

        print("没有出现异常")

    finally:

        print("无论如何,我都会被执行")

    print("ok")

    运行结果:

    E:>python a.py

    请输入一个数字:102

    输入的数字大于100

    无论如何,我都会被执行

    ok

    19、try和except嵌套

    try:

        1/1

        try:                 #该代码块抛出异常后,执行外部的except语句

            1/0

        except:

            raise           #raise后不必非得跟错误名称 ,触发异常向上处理

            print("未知异常1")    

    except:

        print("未知异常2")    

    运行结果:

    E:>python a.py

    未知异常2

     try:
        1/1
        try:
            1/0
        except:
            print("raise")#看内层的except是否有执行
            raise
    except:
        print("未知错误!") 

     -----------------------------------------------------------

    小知识:

    如何判断一个字符串是json串。

    提示:json串的特点是:

    {
        "employees": [
            {
                "firstName": "Bill",
                "lastName": "Gates"
            },
            {
                "firstName": "George",
                "lastName": "Bush"
            },
            {
                "firstName": "Thomas",
                "lastName": "Carter"
            }
        ]
    }

    >>> import json

    >>> d={1:"a"}

    >>> s=json.dumps(d)         #将字典转换成json串

    >>> s

    '{"1": "a"}'

    >>> s=json.loads(s)           #将json串转成字典

    >>> s

    {'1': 'a'}

    import json
    d={1:'a'}
    s=json.dumps(d)
    print(s,type(s))
    d=json.loads("xxxx")
    print(type(d))
     

    使用该知识实现判断一个字符串是不是个合法的json串的异常的应用场景实例:

    import json
    d='xxxxxxx'
    try:
        d=json.loads(d)
    except:
        print("不是一个合法的json串类型")

    ----------------------------------------------------------------------

    小练习:

    1. 使用try:except拦截不同的异常,并给出具体的错误信息。

    try:

        open("e:\ab.txt")

        result=1/0

    except ZeroDivisionError:

        print("除0错误")

    except FileNotFoundError:

        print("文件不存在")

    print("Done")

    运行结果:

    E:>python a.py

    文件不存在

    Done

     
    20、异常和if
    def div(a,b):
        try:
            result = a/b
        except TypeError:
            print("出现了类型不匹配的情况")
        except ZeroDivisionError:
            print("被除数为0的异常出现了")
     
    print(div(2,1))
    print(div(1,"x"))
    print(div(1,0))
     ------------------------------------------------
    def div(a,b):
        if not (isinstance(a,(int,float)) and 
    isinstance(b,(int,float))):
           print("不全是数字!")
           return None 
        try:
            result = a/b
        except TypeError:
            print("出现了类型不匹配的情况")
        except ZeroDivisionError:
            print("被除数为0的异常出现了")
        
    print(div(2,1))
    print(div(1,"x"))
    print(div(1,0))
     
     
  • 相关阅读:
    针对Ext js的分页存储过程适用于sqlserver2008
    30分钟LINQ教程
    windows server 2003 sp2安装VS2010之后需要打的几个布丁
    【翻译】Prism4:初始化Prism应用程序(上)
    ASP.NET WebAPI 路由规则与POST数据
    基于.net开发chrome核心浏览器【二】
    六种SQL Server删除重复行的方法
    Web在线操作Office文件 (转)
    ASP.NET 中如何对生成的 HTML 内容流进行控制?
    使用键值表实现通用流水号(转)
  • 原文地址:https://www.cnblogs.com/suitcases/p/10440767.html
Copyright © 2020-2023  润新知