zoukankan      html  css  js  c++  java
  • 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()
    

      

  • 相关阅读:
    模板 无源汇上下界可行流 loj115
    ICPC2018JiaozuoE Resistors in Parallel 高精度 数论
    hdu 2255 奔小康赚大钱 最佳匹配 KM算法
    ICPC2018Beijing 现场赛D Frog and Portal 构造
    codeforce 1175E Minimal Segment Cover ST表 倍增思想
    ICPC2018Jiaozuo 现场赛H Can You Solve the Harder Problem? 后缀数组 树上差分 ST表 口胡题解
    luogu P1966 火柴排队 树状数组 逆序对 离散化
    luogu P1970 花匠 贪心
    luogu P1967 货车运输 最大生成树 倍增LCA
    luogu P1315 观光公交 贪心
  • 原文地址:https://www.cnblogs.com/frank-shen/p/10279823.html
Copyright © 2011-2022 走看看