Python 闭包及装饰器

闭包是指延伸了作用域的函数。

自由变量(free variable) 指未在本地作用域中绑定的变量 

函数装饰器用于在源码中标记函数, 以某种方式增强函数的行为。

装饰器实质,把被装饰的函数替换为新函数, 二者接收相同的参数,绑定了被装饰函数最为自由变量,返回被装饰函数本该返回的值,同时还会做些额外操作

装饰器的一个特性就是他们在被装饰的函数定义之后立即执行

实现一个简单的装饰器:

def decorate(func):
def inner(*args, **kwargs):
print("我是装饰器")
func(*args, **kwargs)
return inner


@decorate # 相当于 func = decorator(func(*args, **kwargs)) = inner(*args, **kwargs) 同时绑定了被装饰函数的引用作为自由变量
def func(*args, **kwargs):
pass


@decorate
class Test(*args, **kwargs): # 相当于 Test = decorate(Test(*args, **kwargs)) = inner(*args, **kwargs) 同时绑定了被装饰函数的引用作为自由变量
pass


print(func.__code__.co_freevars) # 查看自由变量
print(func.__code__.co_varnames) # 查看局部变量

 叠加装饰器:

def decorate1(func):
    def inner1(*args, **kwargs):
        print("装饰器1开始装饰")
        func(*args, **kwargs)
        print("装饰器1装饰结束")
    return inner1


def decorate2(func):
    def inner2(*args, **kwargs):
        print("装饰器2开始装饰")
        func(*args, **kwargs)
        print("装饰器2装饰结束")
    return inner2

@decorate1    # 相当于 func = decorate1(decorate2(func(*args, **kwargs)))  = inner1(inner2)同时绑定了被装饰函数的引用作为自由变量
@decorate2
def func(*args, **kwargs):
    pass

 参数化装饰器:

创建一个装饰器工厂函数,将参数传给它,返回一个装饰器, 再应用到被装饰的函数上

def register(active=True):
def decorate(func):
def inner(*args, **kwargs):
print('before')
func(*args, **kwargs)
if active:
print('another operation')
print('after')
return inner
return decorate


@register(True) # 相当于 func = decorate(func(*args, **kwargs)) = inner(*args, **args) 同时绑定了参数active以及被装饰函数的引用作为自由变量
def func(a=1):
print(a)

print(func.__code__.co_freevars)

 类实现装饰器  

class Decorator:
    def __init__(self, func):
        self._func = func

    def __call__(self, *args, **kwargs):
        print('__call__')
        self._func(*args, **kwargs)

@Decorator
def func(*args, **kwargs):      # func = Decorator(func(*args, **kwargs))  =  obj  同时绑定了被装饰函数的引用作为实例
    pass


func()

 参数化类装饰器 : 类作为装饰器工厂, 实例为装饰器, 参数保存再实例中,将实例作为装饰器应用到被装饰函数上

class Decorator:
    def __init__(self, active):
        self._active = active

    def __call__(self, func):
        def wrapper(*args, **kwargs):
            if self._active:
                print("another operation")
            func(*args, **kwargs)
        return wrapper

@Decorator(active=True)
def func(*args, **kwargs):      # func = obj(func(*args, **kwargs))  =  wrapper(*args, **kwargs)  同时绑定了参数active作为实例
    pass


func()

  

原文地址:https://www.cnblogs.com/frank-shen/p/10279823.html