美文网首页
13-异常处理&代码调试&单例模式

13-异常处理&代码调试&单例模式

作者: 郑元吉 | 来源:发表于2018-12-08 14:03 被阅读4次

    一、错误和异常

    1.概念

    两种容易辨认的错误

    ​ 语法错误:一些关于语法的错误【缩进】

    ​ 异常:代码完全正确,但是,程序运行之后,会报出 的错误

    exception/error

    代码演示:

    list1 = [23,54,6,6]
    print(list1[2])
    print(list1[3])
    print(list1[4])  
    
    print("over")
    
    """
    6
    6
    Traceback (most recent call last):
      File "C:/Users/Administrator/Desktop/SZ-Python/Day15Code/textDemo01.py", line 4, in <module>
        print(list1[4])
    IndexError: list index out of range
    """
    

    异常特点:当程序在执行的过程中遇到异常,程序将会终止在出现异常的代码处,代码不会继续向下执行

    解决问题:越过异常,保证后面的代码继续执行【实质:将异常暂时屏蔽起来,目的是为了让后面的代码的执行不受影响】

    2.常见的异常

    NameError:变量未被定义

    TypeError:类型错误

    IndexError:索引异常

    keyError:

    ValueError:

    AttributeError:属性异常

    ImportError:导入模块的时候路径异常

    SyntaxError:代码不能编译

    UnboundLocalError:试图访问一个还未被设置的局部变量

    3.异常处理方式

    捕获异常

    抛出异常

    3.1捕获异常
    try-except-else

    语法:

    ​ try:

    ​ 可能存在异常的代码

    ​ except 错误表示码 as 变量:

    ​ 语句1

    ​ except 错误表示码 as 变量:

    ​ 语句2

    ​ 。。。

    ​ else:

    ​ 语句n

    说明:

    ​ a.try-except-else的用法类似于if-elif-else

    ​ b.else可有可无,根据具体的需求决定

    ​ c.try后面的代码块被称为监测区域【检测其中的代码是否存在异常】

    ​ d.工作原理:首先执行try中的语句,如果try中的语句没有异常,则直接跳过所有的except语句,执行else;如果try中的语句有异常,则去except分支中进行匹配错误码,如果匹配到了,则执行except后面的语句;如果没有except匹配,则异常仍然没有被拦截【屏蔽】

    代码演示:

    #一、try-except-else的使用
    
    #1.except带有异常类型
    try:
        print(10 / 0)
    except ZeroDivisionError as e:
        print("被除数不能为0",e)
    
    print("~~~~")
    """
    总结:
    a.try-except屏蔽了异常,保证后面的代码可以正常执行
    b.except ZeroDivisionError as e相当于声明了一个ZeroDivisionError类型的变量【对象】,变量e中携带了错误的信息
    """
    
    #2.try后面的except语句可以有多个
    class Person(object):
        __slots__ = ("name")
    try:
        p = Person()
        p.age = 19
    
        print(10 / 0)
    except AttributeError as e:
        print("属性异常",e)
    except ZeroDivisionError as e:
        print("被除数不能为0",e)
    
    print("over")
    
    """
    总结:
    a.一个try语句后面可以有多个except分支
    b.不管try中的代码有多少个异常,except语句都只会被执行其中的一个,哪个异常处于try语句的前面,则先先执行对应的except语句
    c.后面的异常不会报错【未被执行到】
    """
    
    #3.except语句的后面可以不跟异常类型
    try:
        print(10 / 0)
    except:
        print("被除数不能为0")
    
    
    #4.一个except语句的后面可以跟多种异常的类型
    #注意:不同的异常类型使用元组表示
    try:
        print(10 / 0)
    except (ZeroDivisionError,AttributeError):
        print("出现了异常")
    
    
    #5.else分支
    try:
        print(10 / 4)
    except ZeroDivisionError as e:
        print("出现了异常",e)
    else:
        print("hello")
    
    """
    总结:
    a.如果try中的代码出现了 异常,则直接去匹配except,else分支不会被执行
    b.如果try中的代码没有出现异常,则try中的代码正常执行,except不会被执行,else分支才会被执行
    """
    
    #6.try中不仅可以直接处理异常,还可以处理一个函数中的异常
    def show():
        x = 1 / 0
    
    try:
        show()
    except:
        print("出现了异常")
    
    #7.直接使用BaseException代替所有的异常
    try:
        y = 10 / 0
    except BaseException as e:
        print(e)
    
    """
    总结:在Python中,所有的异常其实都是类,他们都有一个共同的父类BaseException,可以使用BaseException将所有异常“一网打尽”
    """
    
    try-except-finally

    语法:

    ​ try:

    ​ 可能存在异常的代码

    ​ except 错误表示码 as 变量:

    ​ 语句1

    ​ except 错误表示码 as 变量:

    ​ 语句2

    ​ 。。。

    ​ finally:

    ​ 语句n

    说明:不管try中的语句是否存在异常,不管异常是否匹配到了except语句,finally语句都会被执行

    作用:表示定义清理行为,表示无论什么情况下都需要进行的操作

    代码演示:

    #二、try-except-finally的使用
    
    #1.
    try:
        print(10 / 5)
    except ZeroDivisionError as e:
        print(e)
    
    finally:
        print("finally被执行")
    
    
    #2.特殊情况
    #注意:当在try或者except中出现return语句时,finally语句仍然会被执行
    def show():
        try:
            print(10 / 0)
            return
        except ZeroDivisionError as e:
            print(e)
    
        finally:
            print("finally被执行~~~~")
    
    show()
    
    3.2抛出异常

    raise抛出一个指定的异常对象

    语法:raise 异常对象 或者 raise

    说明:异常对象通过错误表示码创建,一般来说错误表示码越准确越好

    代码演示:

    #raise的使用主要体现在自定义异常中
    
    #1.raise表示直接抛出一个异常对象【异常是肯定存在的】
    #创建对象的时候,参数表示对异常信息的描述
    try:
        raise NameError("hjafhfja")
    except NameError as e:
        print(e)
    
    print("over")
    
    """
    总结:
    通过raise抛出的异常,最终还是需要通过try-except处理
    """
    
    #2.如果通过raise抛出的异常在try中不想被处理,则可以通过raise直接向上抛出
    try:
        raise NameError("hjafhfja")
    except NameError as e:
        print(e)
        raise
    

    4.assert断言

    对某个问题做一个预测,如果预测成功,则获取结果;如果预测失败,则打印预测的信息

    代码演示:

    def func(num,divNum):
    
        #语法:assert表达式,当出现异常时的信息描述
        #assert关键字的作用:预测表达式是否成立,如果成立,则执行后面的代码;如果不成立,则将异常的描述信息打印出来
        assert (divNum != 0),"被除数不能为0"
    
        return  num / divNum
    
    print(func(10,20))
    print(func(10,0))
    

    5.异常的嵌套

    代码演示:

    #需求:去拉萨,乘坐各种交通工具
    print("我要去拉萨")
    
    try:
        print("我准备乘飞机过去")
        raise Exception("由于大雾,飞机不能起飞")
        print("到拉萨了,拉萨真漂亮")
    except Exception as e:
        print(e)
        try:
            print("我准备乘火车过去")
            raise  Exception("由于大暴雨,铁路断了")
            print("到拉萨了,拉萨真漂亮")
        except Exception as e:
            print(e)
            print("我准备跑过去")
            print("到拉萨了,拉萨真漂亮")
    

    6.自定义异常

    实现思路:

    a.定义一个类,继承自Exception类

    b.书写构造函数,属性保存异常信息【调用父类的构造函数】

    c.重写str函数,打印异常的信息

    d.定义一个成员函数,用来处理自己的异常

    代码演示:

    class MyException(Exception):
        def __init__(self,msg):
            super(MyException,self).__init__()
            self.msg = msg
    
        def __str__(self):
            return self.msg
    
        def handle(self):
            print("出现了异常")
    
    try:
         raise MyException("自己异常的类型")
    except MyException as e:
         print(e)
         e.handle()
    

    二、单例设计模式

    1.概念

    什么是设计模式

    ​ 经过已经总结好的解决问题的方案

    ​ 23种设计模式,比较常用的是单例设计模式,工厂设计模式,代理模式,装饰模式

    什么是单例设计模式

    ​ 单个实例【对象】

    ​ 在程序运行的过程中,确保某一个类只能有一个实例【对象】,不管在哪个模块中获取对象,获取到的都是同一个对象

    ​ 单例设计模式的核心:一个类有且仅有一个实例,并且这个实例需要应用在整个工程中

    2.应用场景

    实际应用:数据库连接池操作-----》应用程序中多处需要连接到数据库------》只需要创建一个连接池即可,避免资源的浪费

    3.实现

    3.1模块

    Python的模块就是天然的单例设计模式

    模块的工作原理:

    ​ import xxx,模块被第一次导入的时候,会生成一个.pyc文件,当第二次导入的时候,会直接加载.pyc文件,将不会再去执行模块源代码

    3.2使用new
    __new__():实例从无到有的过程【对象的创建过程】
    

    代码演示:

    class Singleton(object):
        #类属性
        instance = None
    
        #类方法
        @classmethod
        def __new__(cls, *args, **kwargs):
            #如果instance的值不为None,说明已经被实例化了,则直接返回;如果为NOne,则需要被实例化
            if not cls.instance:
                cls.instance = super(Singleton,cls).__new__(*args, **kwargs)
    
            return cls.instance
    
    class MyClass(Singleton):
        pass
    
    #当创建对象的时候自动被调用
    one = MyClass()
    two = MyClass()
    
    print(id(one))
    print(id(two))
    
    print(one is two)
    
    3.3装饰器

    代码演示:

    #单例类:将装饰器作用于一个类上
    def singleton(cls):
        #类属性
        instance = {}
    
        #成员方法
        def getSingleton(*args, **kwargs):
            #思路:如果cls在字典中,则直接返回;如果不存在,则cls作为key,对象作为value,添加到字典中
            if cls not in instance:
                instance[cls] = cls(*args, **kwargs)
            return  instance[cls]
    
        return getSingleton
    
    @singleton
    class Test(object):
        pass
    
    t1 = Test()
    t2 = Test()
    
    print(id(t1) == id(t2))
    print(t1 is t2)
    
    3.4使用在类中

    代码演示:

    #单例类
    class Foo(object):
        #1.声明一个变量【类属性】
        instance = None
    
        #2.向外界提供一个公开的方法,用于返回当前类唯一的对象
        #方法命名格式:defaultInstance,currentInstance ,getInstance
        @classmethod
        def getInstance(cls):
            if cls.instance:
                return cls.instance
            else:
                #实例化
                cls.instance = cls()
                return  cls.instance
    
    obj1 = Foo.getInstance()
    obj2 = Foo.getInstance()
    
    print(id(obj1) == id(obj2))
    print(obj1 is obj2)
    

    相关文章

      网友评论

          本文标题:13-异常处理&代码调试&单例模式

          本文链接:https://www.haomeiwen.com/subject/gjdqhqtx.html