• 单例设计模式、工厂设计模式和装饰器


    单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在,不管实例化多少次就只有一个实例
    单例设计模式的优点是不占内存,每个人都调用一个实例对象

    那在python里面怎么怎么实现单例模式呢,单例模式就是只有一个实例,那肯定是指类在实例化的时候,只会实例化一个,就需要用到类里面的一个内置函数__new__,类就是通过这个函数来进行实例化操作的,它在__init__之前先执行
    那我们知道类是通过__new__函数来进行实例化的,那就好办了,思路就是先判断一下这个类有没有被实例化过,如果实例化过了,那我们就不要调用继续实例化了,返回原来的那个实例,如果没有被实例化才继续实例化
    先写一个普通的类,看一下实例化之后的内存地址,可以看到,正常的一个类,实例化两次,内存地址是不一样的,不是一个对象,如下图:

    再写单例模式,再实例化看内存地址是一样的,重写__new__这个方法,如果想实例化必须调用一个父类的__new__(cls)方法,要不然不能实例化,单例模式的写法也很单一,死记硬背就可以了,代码如下:

    工厂模式就是类继承,就是流水线模式

    本质上由decorator和嵌套的wrapper组成一个共生体,这个共生体我们叫做闭包,闭包满足三个条件
    1、函数嵌套函数
    2、函数返回函数
    3、函数间有参数引用
    满足这三个条件的嵌套函数我们称之为闭包,闭包在python中即为修饰器,因此我们可以将代码写成如下形式:

    @deco
    def f():
    print('hello')
    time.sleep(1)
    print('world')

    python装饰器(fuctional decorators)就是用于拓展原来函数功能的一种函数,目的是在不改变原函数名(或类名)的情况下,给函数增加新的功能,这个函数的特殊之处在于它的返回值也是一个函数,这个函数是内嵌"原"函数的函数

    装饰器的作用:
    1、装饰器的本质还是一个函数  
    2、在不改变函数调用方式的情况下,对函数进行额外功能的封装(装饰器的作用就是为已经存在的对象添加额外的功能)
    3、装饰一个函数,给他加一个其他功能

    import time


    def deco(f):
    def wrapper():
    start_time = time.time()
    f()
    end_time = time.time()
    execute_time = round((end_time - start_time) * 1000, 2)
    print('运行的时间是 %s ms' % execute_time)
    return wrapper


    @deco
    def f():
    print('hello')
    time.sleep(1)
    print('world')


    if __name__ == '__main__':
    f()

    这里的deco函数就是最原始的装饰器,它的参数是一个函数名,然后返回值也是一个函数名,其中作为参数的这个函数f()就在返回函数wrapper()的内部执行,然后在函数f()前面加上@deco,f()函数就相当于被注入了计时功能,现在只要调用f(),它就已经变身为"新的功能更多"的函数了,不需要重复执行原函数

    # 带有固定参数的装饰器
    import time


    def deco(f):
    def wrapper(a, b):
    start_time = time.time()
    f(a, b)
    end_time = time.time()
    execute_time = round((end_time - start_time) * 1000, 2)
    print('运行的时间是 %s ms' % execute_time)
    return wrapper


    @deco
    def f(a, b):
    print('be on')
    time.sleep(1)
    print('result is %d' % (a + b))


    if __name__ == '__main__':
    f(3, 4)

    # 无固定参数的装饰器
    import time


    def deco(f):
    def wrapper(*args, **kwargs):
    start_time = time.time()
    f(*args, **kwargs)
    end_time = time.time()
    execute_time = round((end_time - start_time) * 1000, 2)
    print('运行的时间是 %s ms' % execute_time)
    return wrapper


    @deco
    def f(a, b):
    print('be on')
    time.sleep(1)
    print('result is %d' % (a + b))


    @deco
    def f2(a, b, c):
    print('be on')
    time.sleep(1)
    print('result is %d' % (a + b + c))


    if __name__ == '__main__':
    f(3, 4)
    f2(3, 4, 5)

    # 使用多个装饰器,装饰一个函数
    import time


    def deco01(f):
    def wrapper(*args, **kwargs):
    print("this is deco01")
    start_time = time.time()
    f(*args, **kwargs)
    end_time = time.time()
    execute_time = round((end_time - start_time) * 1000, 2)
    print('运行的时间是 %s ms' % execute_time)
    print("deco01 end here")
    return wrapper


    def deco02(f):
    def wrapper(*args, **kwargs):
    print("this is deco02")
    f(*args, **kwargs)
    print("deco02 end here")
    return wrapper


    @deco01
    @deco02
    def f(a, b):
    print('be on')
    print('result is %d' % (a + b))


    if __name__ == '__main__':
    f(3, 4)

    执行结果如下:

    装饰器调用顺序:
    装饰器是可以叠加使用的,那么使用装饰器以后代码是啥顺序呢?,在这个例子中,"f(3, 4) = deco01(deco02(f(3, 4)))"

  • 相关阅读:
    当tp5项目上传到服务器之后遇见的各种bug(不定期更新)
    解决LAMP下 服务器IP无法访问
    thinkphp5多图上传+同时删除本地文件
    from提交表单后 数据提交到后台 但不跳转页面 非ajax 用iframe
    window7 安装sass和compass
    开源操作系统课程设计
    Hadoop伪分布式搭建实验总结
    排序集合
    快排
    邻接矩阵
  • 原文地址:https://www.cnblogs.com/laosun0204/p/9138974.html
Copyright © 2020-2023  润新知