python开发学习历程day14

2020-06-18                   目录:

一、装饰器

1.1  什么是装饰器

1.2  为何要用装饰器

1.3  怎么用装饰器

二、语法糖

三、装饰器的模板

3.1  模板

3.2  wraps+ 终极模板

一、装饰器

1.1  什么是装饰器

名词解释:
器:即功能/工具
装饰:为被装饰的对象添加额外的功能

1.2  为何要用装饰器

程序开发需要遵循开放封闭原则:即对拓展功能开放,对修改源代码封闭
装饰器:可以在不修改被装饰对象的源代码及其调用方式的前提下,为被装饰对象添加新功能的工具

1.3  怎么用装饰器

比如:为两个简单的打印函数添加程序运行时间测试的功能

import time


def index(x, y):       # 原始index函数
    print(x, y, 'from index')
    time.sleep(1)
    return 111


def name(x):           # 原始name函数
    print('name:%s' % x)
    time.sleep(0.5)
    return 222


def outer(func):     # 闭包函数 为wrapper函数传值(函数名)
    def wrapper(*args, **kwargs):   # 装饰函数,不同函数调用可以接受不同个数、格式的值
        start_time = time.time()    # 添加新功能
        res = func(*args, **kwargs)  # 调用outer传入的func函数,将wrapper汇总的参数打散成原形传进func,并将返回值赋值给res
        end_time = time.time()
        print('running time is %s' % (end_time - start_time))
        return res    # 同于传递原始func函数的返回值

    return wrapper    # 一定不能加括号


index = outer(index)   # index=wrapper  将wrapper装饰过的函数重新绑定给函数名index (不想使用装饰器时删除此行即可)
res1 = index(1, 2)
print(res1)

name = outer(name)   # name = wrapper(同理,不想使用装饰器时删除此行即可)
res2 = name('jason') 
print(res2) 
""" 
运行结果:>>> 1 2 from index running time is 1.000702142715454 111 name:jason running time is 0.5009057521820068 222 """

二、语法糖

@outer  写在被装饰函数定义之前单独一行(必须先定义装饰器outer)
可以替代上面代码里面的 index = outer(index) 和 name = outer(name)  
用来使函数调用时尽量与原函数没有操作上的不同
同样的,不想使用装饰器功能时删除此行就行

三、装饰器的模板

3.1  模板

装饰器的设计即可基于如下模板进行修改、添加需要的功能:

def outer(func):
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        return res
    return wrapper

3.2  wraps+终极模板

使用方法:写在最内层函数正上方

作用:将被装饰函数的种种属性都赋值给新函数,使得装饰过的函数看起来“没有被动过手脚”

于是就有了最完整的终极模板:

from functools import wraps
def outer(func):
    @wraps()  # 写在最内层函数的正上方
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        return res
    return wrapper

 

上一篇:day14函数递归(02)


下一篇:JavaSE基础入门Day14