• Python学习:18.Python异常处理


    一、为什么使用异常处理

      当程序运行的时候出现了异常,导致程序终止运行,为了解决这种情况,我们需要预先对可能出现的异常进行处理,一旦出现这种异常,就使用另一种方式解决问题,还有就是错误信息是使用者没有必要看到的,他们不需要知道内部错误的原因,所以我们需要友好的显示错误信息,这就需要用到异常处理。

    二、简单异常处理

      在以下代码里,首先获取用户输入的值,然后到try代码块里,在try代码块里的代码是收到保护的,如果try中的代码发生了异常,就会执行except中的代码。

      在try中的代码,如果某一句出现了错误,则这一句下面的代码就不再执行,直接执行except中的代码。

    inp = input('请输入内容:')
    try:
        num = int(inp)
        print(num)
    except Exception as e:
        print(e)
        print('数据类型转换失败!')
    
    
    
    输出结果:
    请输入内容:aaa
    invalid literal for int() with base 10: 'aaa'
    数据类型转换失败!

    三、异常处理分类

      在上面的示例中,except后面的Exception是一个包含有错误信息的类,而这个e是创建的Exception的对象,包含着错误信息,比如下面的输出结果。

    li = []
    inp = input('请输入内容:')
    li[int(inp)]
    
    
    输出结果:
    请输入内容:aaa
    Traceback (most recent call last):
      File "C:/Users/Administrator/PycharmProjects/untitled1/Alexsel/gg.py", line 318, in <module>
        li[int(inp)]
    ValueError: invalid literal for int() with base 10: 'aaa'

    这里的ValueError就是异常的一种,接下来我们就了解一下Python中的常见的异常。

    异常描述
    NameError 尝试访问一个没有声明的变量
    ZeroDivisionError 除数为0
    SyntaxError 语法错误
    IndexError 索引超出序列范围
    KeyError 请求一个不存在的字典关键字
    IOError 输入输出错误(比如要读的文件不存在)
    AttrilbuteError 尝试访问未知的对象属性
    ValueError 传给函数的参数类型不正确,比如给int()函数传入字符串
    ImportError 无法引入模块或包,大部分是路径或者名称错误
    IndentationError 语法错误,比如代码没有正确对齐
    KeyboardInterrupt Ctrl+C正被按下
    TypeError 传入对象类型与要求的不符合
    UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量, 导致你以为正在访问它

    四、异常的分类处理

      一个程序运行的时候可能出现多种异常,常见的异常我们在上面都展示给大家了,每种异常都可以根据类型捕捉到,比如出现了ValueError类型的错误,我们可以使用ValueError进行捕捉,其它类型的异常就无法捕捉到,我们可以针对出现的那些异常进行分类处理,以便更好的处理异常。

    li = []
    inp = input('请输入内容:')
    try:
        li[int(inp)]
    except IndexError as ie:
        print('索引错误')
    except ValueError as ve:
        print('参数类型不正确')
    
    
    输出结果:
    请输入内容:aaa
    参数类型不正确

    如果我们不想那么麻烦,想直接捕捉所有类型的异常怎么办,那么我们就使用Exception。

    li = []
    inp = input('请输入内容:')
    try:
        li[int(inp)]
    except Exception as e:
        print(e)
    
    输出结果:
    请输入内容:aaa
    invalid literal for int() with base 10: 'aaa'

    如果想同时使用Exception和单个类型异常捕捉,应该吧单个类型异常的捕捉放到Exception的后面,因为Exception放在前面则直接使用这个捕捉所有的错误,下面的异常处理不再执行。

    之前我们说到Exception是一个类,我们刚才有讲了单个异常处理,例如ValueError,NmaeError等,这些异常都是Exception的派生类。

    五、完整的异常处理结构

    try:
        pass
    except ValueError as e:
        #当try中发生ValueError异常的时候,执行这里的代码
        pass
    except Exception as e:
        pass
    else:
        #try中没有出现异常执行这里的代码
        pass
    finally:
        #最终,无论什么情况,最后都执行这里的代码
        pass

    执行流程

      如果try中的代码出现错误,首先判断是不是ValueError错误,如果是执行,不是执行Exception中的错误处理代码,最终执行finally中的代码。

      如果try中的代码没有出现错误,就行else中的代码,最终执行finally中的代码。

    六、主动触发异常

      之前我们出现的错误都是解释器触发的,我们想要自己触发一个异常需要怎么做,这里我么就要使用到raise。

    try:
        print('alexsel')
        raise Exception('出错了!!!')#这里就是创建了一个Exception对象,下面的e就是这个对象
    except Exception as e:
        print(e)
    
    输出结果:
    alexsel
    出错了!!!

    这里的自己触发的错误以及自定义的错误信息,就直接传递到相应错误类型创建的对象中,在这里就传递到了e中,这个e就是封装了错误信息的一个对象。

    这里我们就针对这个对象,再讲一个类中的特殊成员__str__。

    我们之前说到Exception是一个类,我们刚才使用类Exception('出错了!!')创建了一个对象,然后这个对象就传递给了e,最后我们可以使用print将e的里包含的内容输出,可是我们在对一般的对象输出时就不会输出信息,只会出现该对象内存信息,如下

    class Foo:
        def __init__(self):
            print('init')
    
    obj = Foo()
    print(obj)
    
    
    输出结果:
    init
    <__main__.Foo object at 0x00000000027F1898>

    但是我们在使用异常处理的时候,创建的e也是一个对象,为什么可以使用print打印出错误信息,原因就是在错误处理的类中写了一个特殊的类成员__str__,使用这个之后,创建的使用print打印创建的对象就会输出__str__中返回值返回的内容。

    class Foo:
        def __init__(self,age):
            self.age = age
    
        def __str__(self):
            return self.age
    
    obj = Foo('99')
    print(obj)
    
    
    输出结果:
    99

    这里创建对象的时候传入了age,在我们输出的时候,输出了__str__中的返回值,所以输出了99。

    七、自定义异常处理代码

    我们在刚才知道了raise的用法和为什么可以使用print打印出错误信息,我们就可以使用这两个方法进行自定义异常处理代码,我们就简单做一个例子。

    class MyException(Exception):
        def __init__(self,message):
            self.message = message
    
        def __str__(self):
            return self.message
    
    try:
        print('alexsel')
        raise MyException('我的异常处理!')
    except MyException as e:
        print(e)
    
    输出结果:
    alexsel
    我的异常处理!

    在这里需要注意一下,我们自己写的异常处理的类需要继承Exception,只有这样我们才能成功在raise和except后面使用的时候成功调用。

  • 相关阅读:
    ureport2 数据源配置
    ureport2 + spring boot 搭建
    alibaba
    Maven Helper
    在Idea中连接数据库并生成实体类
    Intellij jrebel 热部署 安装
    IDEA使用说明
    JPA 常用注解 (hibernate)
    vue + canvas 图片加水印
    vue——批量下载图片
  • 原文地址:https://www.cnblogs.com/liudi2017/p/9386753.html
Copyright © 2020-2023  润新知