【设计模式】装饰器模式--Python实现装饰器--闭包

文章目录

      • 一、闭包
          • 1、什么是闭包?
          • 2、作用
      • 二、装饰器 Decorator
        • 1、 概念及特点
          • 1.1 装饰器概念
          • 1.2 遵循原则
          • 1.3 优点
          • 1.4 缺点
          • 1.5 使用场景
          • 1.6 注意事项
          • 1.7 装饰器(decorator)功能
        • 2、代码实现
          • 2.1 被装饰函数无参数 函数计时的装饰器:
          • 2.2 被装饰函数有参数 计时器
          • 2.3 被装饰的函数有不定长参数

**设计模式(Design pattern)**代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。

设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。

一、闭包

1、什么是闭包?

①在函数内部嵌套了一个函数,
②内函数使用了外函数的局部变量,
③并且外函数返回了内函数的引用,这样就构成了一个闭包

def outfunc(a, b):
    def innerfunc(x):
        return x * a + b
    return innerfunc  # 返回闭包的结果,这里没有括号

Python2 和Python3中,内部函数修改外部函数局部变量有差别。

2、作用

闭包可以提高代码的复用性

但需要注意:由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存

二、装饰器 Decorator

1、 概念及特点

1.1 装饰器概念

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

有了装饰器就可以抽离出大量的与函数功能本身无关的雷同代码。

1.2 遵循原则

遵循开放封闭原则,该原则也适用于函数式编程。

简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即:

  • 封闭:已实现的功能代码块
  • 开放:对扩展开发
1.3 优点

装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

1.4 缺点

多层装饰比较复杂。

1.5 使用场景
  • 扩展一个类的功能。

  • 动态增加功能,动态撤销。

1.6 注意事项

可代替继承。

1.7 装饰器(decorator)功能
  • 引入日志

  • 函数执行时间统计

  • 执行函数前预备处理

  • 执行函数后清理功能

  • 权限校验等场景

  • 缓存

2、代码实现

2.1 被装饰函数无参数 函数计时的装饰器:
import time

def timeit(func):
    def innerfunc():
        start = time.time()
        func()
        end = time.time()
        print('Used :', end - start)
	return innerfunc

@timeit
def foo():
    for i in range(100000):
        pass
    
foo()

程序运行到装饰器的时候,会立即对下面的函数进行装饰 带参数的装饰器:

2.2 被装饰函数有参数 计时器
from time import ctime, sleep

def timefun(func):
    def wrapped_func(a, b):
        print("%s used at %s" % (func.__name__, ctime()))
        print(a, b)
        func(a, b)
    return wrapped_func

@timefun
def foo(a, b):
    print(a+b)

foo(5, 3)
sleep(2)
foo(3, 5)
2.3 被装饰的函数有不定长参数
from time import ctime, sleep

def timefun(func):
    def wrapped_func(*args, **kwargs):
        print("%s used at %s"%(func.__name__, ctime()))
        func(*args, **kwargs)
    return wrapped_func

@timefun
def foo(a, b, c):
    print(a+b+c)

foo(2, 5, 7)
sleep(2)
foo(2, 6, 8)

你可能感兴趣的:(Python)