zoukankan      html  css  js  c++  java
  • ~~面向对象进阶(七):异常捕获~~

    进击のpython

    *****

    异常捕获


    什么叫做异常捕获???我们分开来理解

    什么是异常??什么又叫捕获呢?


    异常?那不是你经常做出来的嘛

    不信??

    你看看这些,你熟悉不??

    NameError: name 'w' is not defined
    ValueError: invalid literal for int() with base 10: 'w'
    TypeError: 'int' object is not iterable
    SyntaxError: Non-UTF-8 code starting with 'xce' in file
        ...
    

    是不是都是你曾经的杰作呢???

    呐,又要开始学新的英语单词了

    Error : 错误,异常

    那么NameError就是变量异常

    同理TypeError就是类型异常

    看!一场是不是就出来了!

    异常其实说白了不就是

    你平时写代码出来的各种报错吗!

    哈哈哈,扎铁了老心!


    那既然我们已经知道了什么是异常了

    那捕获呢?捕捉是个动词是吧

    (哥哥,你别告诉我你不知道这是动词)

    那我们为什么要捕获异常呢?

    一个最简单的例子,我要输入两个数字,然后求和

    因为用户的输入都是字符串类型是吧

    (不知道???那我就想锤你了)

    所以我们是不是还需要把字符串类型的数字变成整型

    是不是就要用int()给他处理一下!

    对吧!逻辑没问题吧

    但是你又发现了,我要是输入的不是数字,就会给我报错

    然后程序就终止了!

    但是我想做的是报错了,我就跟他说你错了,然后程序重新运行

    这要求不过分吧!那么就要用到异常捕获了!

    如果你有异常,我就给你抓起来,不让你报错,那你程序不就能执行了嘛

    如果我再想提示你个什么信息我就写出来就完事了呗

    那理论有了,我们来看看这玩仍到底怎么写


    两个关键字 try except

    while 1:
        try:
            m = int(input("请输入第一个加数:"))
            n = int(input("请输入第二个加数:"))
            print(m + n)
        except:
            print("请输入数字")
    

    用上面两个关键字把你要捕捉异常的代码放进去("就是你觉得可能会报错的代码块!")

    这个写法格式就有点像 if-elif 的格式写法

    好了!基本的格式和写法就是这样的

    但是啊,以你现在的技术,你就会报一个错误??

    想什么呢凑弟弟!

    还不是改一个又出来一个错误!

    那这么多错误,我想针对不同的错误,有不同的提示

    要怎么写呢?????


    这就用到了咱们最先的学到的那几个英语单词了

    简单来说就是用 不同的网抓不同的鱼

    我们有多少张网呢?

    给你点常用的先感受一下

    AttributeError 试图访问一个对象没有的属性,比如foo.x,但是foo没有属性x
    
    IOError 输入/输出异常;基本上是无法打开文件
    
    ImportError 无法引入模块或包;基本上是路径问题或名称错误
    
    IndentationError 语法错误(的子类) ;代码没有正确对齐
    
    IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
    
    KeyError 试图访问字典里不存在的键
    
    KeyboardInterrupt Ctrl+C被按下
    
    NameError 使用一个还未被赋予对象的变量
    
    SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
    
    TypeError 传入对象类型与要求的不符合
    
    UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它
    
    ValueError 传入一个调用者不期望的值,即使值的类型是正确的
    

    再给你点不常用的,你看看就好

    ArithmeticError
    
    AssertionError
    
    AttributeError
    
    BaseException
    
    BufferError
    
    BytesWarning
    
    DeprecationWarning
    
    EnvironmentError
    
    EOFError
    
    Exception
    
    FloatingPointError
    
    FutureWarning
    
    GeneratorExit
    
    ImportError
    
    ImportWarning
    
    IndentationError
    
    IndexError
    
    IOError
    
    KeyboardInterrupt
    
    KeyError
    
    LookupError
    
    MemoryError
    
    NameError
    
    NotImplementedError
    
    OSError
    
    OverflowError
    
    PendingDeprecationWarning
    
    ReferenceError
    
    RuntimeError
    
    RuntimeWarning
    
    StandardError
    
    StopIteration
    
    SyntaxError
    
    SyntaxWarning
    
    SystemError
    
    SystemExit
    
    TabError
    
    TypeError
    
    UnboundLocalError
    
    UnicodeDecodeError
    
    UnicodeEncodeError
    
    UnicodeError
    
    UnicodeTranslateError
    
    UnicodeWarning
    
    UserWarning
    
    ValueError
    
    Warning
    
    ZeroDivisionError
    

    我们有这么多张网,怎么用呢?

    上面的程序,如果我输入的是非数字是不是报的是ValueError

    (你要不知道,你就把 try-except 去掉,然后输入非数字,你看看提示的是什么)

    (别的找错方式也可以这样!)

    那我们就可以这么写

    while 1:
        try:
            m = int(input("请输入第一个加数:"))
            n = int(input("请输入第二个加数:"))
            print(m + n)
        except ValueError:
            print("请输入数字")
    

    为什么说是和 if-elif 相似的格式呢?

    if-elif 是不是多选一啊

    我们也可以!

    while 1:
        try:
            k
            m = int(input("请输入第一个加数:"))
            n = int(input("请输入第二个加数:"))
            print(m + n)
    
        except ValueError:
            print("请输入数字")
    

    看,我是不是定义个变量,但是没有赋值,那就回报这个错误:NameError: name 'k' is not defined

    我们要是想抓这条鱼,怎么做呢?多选一嘛!

    while 1:
        try:
            k
            m = int(input("请输入第一个加数:"))
            n = int(input("请输入第二个加数:"))
            print(m + n)
    
        except ValueError:
            print("请输入数字")
        except NameError:
            print("含有未定义的变量")
    

    对吧!是不是写法挺像 if-elif 的

    如果你想两个不同的错误都提示相同的信息

    你也可以进行合写!

    except (ValueError,NameError)
    

    那,是什么错误,都能捕获吗?????


    a = 100
    if a == 100:
    print("hahah")
    

    会报错,报了一个什么错呢? IndentationError: expected an indented block

    那我们就用 try-except 来捕捉这个错误

    练习自己捕捉!

    你会发现这个错误你是捕捉不了的

    其实不光是这个错误,还有些别的错误你也是捕捉不到的

    什么语法错误 SyntaxError: invalid syntax 啊之类的

    就等你自己发现啦!


    那,很明显

    我要是错误很多,然后除了几个错误之外,别的我都不想写了

    那我可以推荐你个好方法!万能异常!

    简单来说就是一堵墙,它可以拦住漏过你前面网的所有鱼

    那既然我都这么说了

    很明显,这堵墙的位置应该在所有网的最后面

    这堵墙长什么样呢?

    except Exception:
    

    那除了那么写的,还有别的

    你想啊 if-elif 是不是后面还可以延伸一个else?

    那try-except 也可以延伸出一个else

    if-elif-else else是不是放在最后?

    那 try-except-else 中的else也应该放在最后

    if-elif-else 中的else是不是所有的都没执行才执行else?

    那try-except-else 中的else就应该是所有错误都没出才执行!

    对吧!类比学习嘛!


    那除了除了以上的格式,其实还有别的

    try-except-else-finally 多了个finally

    那finally的作用其实就是你错没错都是会执行的

    (代码自己敲!很简单的)


    那我们为了工作需要,有的时候也会主动抛出异常

    那主动抛出异常就有要学一个词了:raise

    他就会抛出一个指定的异常,比如 raise NameError

    就是我主动抛出一个叫做 NameError 的异常

    那我主动抛出异常有什么用呢??

    比如在以后的某天,你厉害了,自己写了个软件

    那对于应用级的异常,就只能自己抛出特殊的异常

    (而这个异常,往往是自己定义的,下面会提)

    那这个时候就需要raise


    我们可以学一下如何自定义一个异常

    其实你定义的所有异常,都是继承一个叫BaseException类

    (你别告诉我你不知道继承是啥)

    我们可以把错误信息放在构造函数里面

        def __init__(self, msg):
            self.msg = msg
    

    然后我们还要再写一个这个

        def __Str__(self):
            return self.msg
    

    最后我们进行拼装一下,并进行测试

    class MyError(BaseException):
        def __init__(self, msg):
            self.msg = msg
    
        def __Str__(self):
            return self.msg
    
    
    try:
        raise MyError("我错了!")
    except MyError as e:
        print(e)
    

    自己看结果

    同时啊,这里还要强调一点

    就是这种自己搞得异常,万能异常都是捕捉不到的!


    *别走开*
    *下节更精彩*
  • 相关阅读:
    TP5常用函数总结1
    swiper 自定义的一些需求
    jQuery 点击元素以外任意地方隐藏该元素
    fastadmin中编辑时的fieldlist选项类型,如何跟数据库里的保持一致,并且显示匹配的样式
    leetcode——63. 不同路径 II
    leetcode——62.不同路径
    数组标签结束,下一个标签,动态规划
    leetcode——48. 旋转图像
    leetcode——45. 跳跃游戏 II
    leetcode——41. 缺失的第一个正数
  • 原文地址:https://www.cnblogs.com/jevious/p/11283795.html
Copyright © 2011-2022 走看看