python学习笔记——闭包与装饰器

def w1(func):
    def inner():
        print('test')
        return func()
    return inner
@w1
def f1():
    print('f1')

这一段代码很好的解释了装饰器与闭包的基本构成,下面分析一下它的运作过程:

· 首先程序识别第一行,将w1函数加入内存

· 识别到@w1,这是python中的语法糖,他会将下面一个函数f1作为参数传入w1

· 这时,w1内部会一行一行地执行:

    def inner():
        print('test')  # 这就是向原程序添加的功能
        return func() #此时,函数func代表的就是f1
    return inner  # 全部执行完,返回一个非执行函数inner
· w1执行完后,我们得到了inner这个返回值,inner包含了原功能和新功能

· 我们想要保持原函数不变,即调用f1时就执行新功能,那怎么做呢,就是让函数名f1指向函数inner,@w1干的就是这件事儿

· 此时,f1.__name__是inner,而不是f1了

实质上,我们是把f1函数装入了inner中这就叫闭包,调用f1时,实质上是调用了函数inner,它内部执行了一系列操作后再返回f1原功能,好像f1 被装饰了一样,这就叫装饰器

但是,返回的那个inner函数的名字本来就是inner,所以我们要把原始函数f1的__name__等属性赋值给inner,否则某些依赖函数属性的代码会报错。

一种写法是inner.__name__ = f1.__name__,这种写法完全没毛病,但是太不pythonnic了,functools里的wraps()就是做这个的 

import functools

def w1(func):
    @functools.wraps(func)
    def inner():
        print('test')
        return func()
    return inner
这时,在打印f1.__name__就是f1了


你可能感兴趣的:(python学习笔记——闭包与装饰器)