• Python3 与 C# 面向对象之~异常相关


    周末多码文,昨天晚上一篇,今天再来一篇:

    在线编程:https://mybinder.org/v2/gh/lotapp/BaseCode/master

    在线预览:http://github.lesschina.com/python/base/oop/3.异常相关.html

    代码裤子:https://github.com/lotapp/BaseCode/tree/master/python/2.OOP/4.Exception

     

    1.异常

    1.1 try...except

    又到了开新课的时候了,小明同学这次提前预习了知识,乘着老师还没来就在黑板上写下了这段Code:

    In [1]:
    def main():
        try:
            1 / 0  # ZeroDivisionError: division by zero
        except ZeroDivisionError as ex:
            print(ex)
    
    
    if __name__ == '__main__':
        main()
    
     
    division by zero
    
     

    1.2 try...except...else...finally

    小潘同学刚进来就看见了,自语道:“try...except捕获异常谁不会?就会这么屁点东西还好意思秀,切~ 我给你把 格式补全”

    于是乘着小明上厕所的时候,擦掉小明的Code,自己写了一段高大上的Code:

    In [2]:
    # 异常捕获全格式
    def test(input_str):
        try:
            eval(input_str)
        except ZeroDivisionError as ex:
            print("except:", ex)
        else:
            print("else:没有异常就奖励100块~")
        finally:
            print("finally:小明是傻子~")
    
    
    def main():
        test("1/0")
        print("-" * 10)
        test("print('小明啊小明你调坑里了~')")
    
    
    if __name__ == '__main__':
        main()
    
     
    except: division by zero
    finally:小明是傻子~
    ----------
    小明啊小明你调坑里了~
    else:没有异常就奖励100块~
    finally:小明是傻子~
    
     

    这时候小明和老师一起进来了,同学们隐约间都听到小明的自夸声:“老师,我可好了,提前预习并且还写了个demo在黑板上呢~”

    老师一进门看着黑板就笑了,同学们也笑成一片。小明心想,咦~难道我写错了?定眼一看黑板,气呼呼的回座位了

    else可以不写,不过我们 基本上还是会写的,毕竟可以知道是真的没有错误,而不是屏蔽了错误

    1.3 多个异常处理

    老师很欣慰,觉得这个班真有意思,大家学习空前热情,为了照顾小明,老师反问道:“有谁知道 多个异常怎么处理?”

    小明飞快的举手并把黑板上内容擦完,写下了如下代码:

    In [3]:
    # 多个异常捕获
    def main():
        try:
            print(xiaopan)  # NameError: name 'xiaopan' is not defined
            1 / 0  # ZeroDivisionError: division by zero
        except NameError as ex:
            print(ex)
        except ZeroDivisionError as ex:
            print(ex)
    
    if __name__ == '__main__':
        main()
    
     
    name 'xiaopan' is not defined
    
     

    老师问了小明一声,有几个输出?

    小明骄傲的说道:“两个,我写了两个异常处理,当然都执行了”

    同学们又笑了,小潘调侃的说了句:“一看就知道去年C#没好好学,这不都一样嘛,遇到异常下面代码还执行吗?用脑子好好想想”

    当我们认为某些代码可能会出错时,就可以用try来运行这段代码,如果执行出错,则后续代码不会继续执行,而是直接跳转至except语句块,执行完except后,如果有finally语句块,则执行finally语句块

    小明又尴尬了。。。

    1.4 多异常简写

    老师再次帮小明圆了个场:“已经很不简单了,就是最后小得意的时候口误了,那小明同学你知道Python里面多异常有个便捷写法吗?”

    小明赶紧拿起粉笔刷刷刷的写完,然后说道:“of course

    In [4]:
    # 多个异常捕获的简写(注意哦,是元组哦)
    def main():
        try:
            print(xiaopan)  # NameError: name 'xiaopan' is not defined
            1 / 0  # ZeroDivisionError: division by zero
        except (NameError, ZeroDivisionError) as ex:
            print(ex)
    
    
    if __name__ == '__main__':
        main()
    
     
    name 'xiaopan' is not defined
    
     

    老师赶紧夸了夸小明,心想,哎呦喂终于把这难缠的家伙弄回座位了。

    小明走前还不忘说一句:“简写的时候注意格式哦,是 元组 不是逗号分隔”

    老师这堂课很轻松,大家都预习了而且内容也比较简单。

    接着以提问的方式问道:“小潘同学,你知道异常的基类是什么吗?如果要捕获所有异常该怎么做呢?”

    小潘站起来说道:“是BaseException

    老师扩充道:“所有的错误类型都继承自BaseException,所以在使用except时需要注意的是,它不但捕获该类型的错误,还把其子类也一起捕获了”

    所以一般在捕获异常的时候 把子类异常放在前面,父类放在后面

    看如下代码:

    In [5]:
    def main():
        try:
            1 / 0  # ZeroDivisionError: division by zero
        except BaseException as ex:
            print("base:", ex)
        except ZeroDivisionError as ex:
            print(ex)
    
    
    if __name__ == '__main__':
        main()
    
     
    base: division by zero
    
     

    如果把父类放第一个,那么ZeroDivisionError永远也不会被执行了,其实你如果装了 代码规范提示插件会提示你的

    可以参考我之前写的 vscode设置python3调试环境的扩充部分

    来个通用异常捕获的简写(官方不推荐使用简写):

    In [6]:
    # 直接except就行了
    def main():
        try:
            1 / 0
            dnt += 1
        except:
            print("屏蔽错误")
    
    
    if __name__ == '__main__':
        main()
    
     
    屏蔽错误
    
     

    老师继续讲到,我们来看一个场景,现在很多在线编辑器,你在他们那些编辑框里写下了代码也是有异常抛出的,这是怎么处理的呢?

    微软有开源代码编辑器比较受欢迎(VSCode的一部分):monaco-editor

    提示一下,如果真的要做在线编辑器,记得考虑一下fork炸弹,这个其实也是很老的东西了,程序员基本上都应该接触过了

    1.5 抛出异常

    我们继续,像C#是用thorw抛出异常,那Python怎么 捕获异常后再抛出 呢?怎么自定义异常 呢?

    继续往下看:

    In [7]:
    # 捕获异常后再丢出,eg:在线运行的用户Code
    def main():
        try:
            1 / 0  # ZeroDivisionError: division by zero
        except ZeroDivisionError as ex:
            print(ex)  # 写个日志,回头出问题可以深究
            raise
    
    
    if __name__ == '__main__':
        main()
    
     
    division by zero
    
     
    ---------------------------------------------------------------------------
    ZeroDivisionError                         Traceback (most recent call last)
    <ipython-input-7-15f01346e2d8> in <module>()
          9 
         10 if __name__ == '__main__':
    ---> 11main()
    
    <ipython-input-7-15f01346e2d8> in main()
          2 def main():
          3     try:
    ----> 41 / 0  # ZeroDivisionError: division by zero
          5     except ZeroDivisionError as ex:
          6         print(ex)  # 写个日志,回头出问题可以深究
    
    ZeroDivisionError: division by zero
    In [8]:
    # 抛出自定义异常
    class DntException(BaseException):
        pass
    
    
    def get_age(num):
        if num <= 0:
            raise DntException("num must>0")
        else:
            print(num)
    
    
    def main():
        get_age(-1)
        get_age(22)  # 程序崩了,这句话不会被执行了
    
    
    if __name__ == '__main__':
        main()
    
     
    ---------------------------------------------------------------------------
    DntException                              Traceback (most recent call last)
    <ipython-input-8-7c9dec6ec225> in <module>()
         17 
         18 if __name__ == '__main__':
    ---> 19main()
    
    <ipython-input-8-7c9dec6ec225> in main()
         12 
         13 def main():
    ---> 14get_age(-1)
         15     get_age(22)  # 程序崩了,这句话不会被执行了
         16 
    
    <ipython-input-8-7c9dec6ec225> in get_age(num)
          6 def get_age(num):
          7     if num <= 0:
    ----> 8raise DntException("num must>0")
          9     else:
         10         print(num)
    
    DntException: num must>0
     

    异常这一块基本上讲完了(logging模块后面会说)有什么补充的可以说的^_^

     

    1.6 C#异常

    小明又进行了C#的代码转换,怎么看都觉得还是C#简单啊,根本不用说啥,代码一贴就秒懂了。。。

    In [1]:
    %%script csharp
    try
    {
        Convert.ToInt32("mmd");
    }
    catch (Exception ex)
    {
        // Input string was not in a correct format
        Console.WriteLine(ex.Message);
    }
    
     
    Input string was not in a correct format.
    
    In [2]:
    %%script csharp
    //抛出自定义异常
    try
    {
        throw new Exception("出错了啊");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    
     
    出错了啊
    
     

    你可以自定义异常类,继承Exception即可,对了C#里面也是有finally的

    try
    {
        throw new Exception("出错了啊");
        //Convert.ToInt32("mmd");
    }
    catch (Exception ex)
    {
        // Input string was not in a correct format
        Console.WriteLine(ex.Message);
    }
    finally
    {
        Console.WriteLine("finally");
    }
    

    现在一些需要finally的地方基本上都被using(){}接管了,所以特定场景会使用

    先这样了

  • 相关阅读:
    TDD测试驱动开发
    力导向算法研究
    简单软件破解入门
    学习Go语言之模板方法模式
    学习Go语言之观察者模式
    学习Go语言之使用channel避免竞态问题
    学习Go语言之使用原子访问或互斥锁解决竞态问题
    使用 Beego 搭建 Restful API 项目
    学习Go语言之抽象工厂模式
    [转载]几张图看懂区块链技术到底是什么?
  • 原文地址:https://www.cnblogs.com/dunitian/p/9220368.html
Copyright © 2020-2023  润新知