Python 参数化装饰器

在解析源码中的装饰器时,Python 会把被装饰的函数作为第一个参数传给装饰器函数,那怎么让装饰器接受其他参数呢? 

答案是建立一个装饰器工厂函数,返回一个装饰器,然后再把它应用到要装饰的函数上。

举例:

# BEGIN REGISTRATION

registry = []  # <1>

def register(func):  # <2>
    print('running register(%s)' % func)  # <3>
    registry.append(func)  # <4>
    return func  # <5>

@register  # <6>
def f1():
    print('running f1()')

@register
def f2():
    print('running f2()')

def f3():  # <7>
    print('running f3()')

def main():  # <8>
    print('running main()')
    print('registry ->', registry)
    f1()
    f2()
    f3()

if __name__=='__main__':
    main()  # <9>

# END REGISTRATION

为了便于 register 执行的函数注册供能,我们提供一个可选的 active 参数,设为 False 时,不注册被装饰的函数。

# BEGIN REGISTRATION_PARAM

registry = set()  # <1>

def register(active=True):  # <2>
    def decorate(func):  # <3>
        print('running register(active=%s)->decorate(%s)'
              % (active, func))
        if active:   # <4>
            registry.add(func)
        else:
            registry.discard(func)  # <5>

        return func  # <6>
    return decorate  # <7>

@register(active=False)  # <8>
def f1():
    print('running f1()')

@register()  # <9>
def f2():
    print('running f2()')

def f3():
    print('running f3()')

# END REGISTRATION_PARAM

如上所示,新的 register 函数不是装饰器,而是装饰器工厂函数,调用它会返回真正的装饰器,这才是应用到目标函数的装饰器。

只有 f2 函数在 register 中,f1 不在其中,因为传给 register 装饰器工厂函数的参数时 active = False,所以应用到 f1 上的 decorate 没有把它添加到 registry 中。decorate 是装饰器,register 是装饰器工厂函数。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值