万字深度解析Python装饰器,你学废了吗?(1),程序员必看

def debug(func):

def wrapper():

print “[DEBUG]: enter {}()”.format(func.name)

return func()

return wrapper

def say_hello():

print “hello!”

say_hello = debug(say_hello) # 添加功能并保持原函数名不变

上面的 debug 函数其实已经是一个装饰器了,它对原函数做了包装并返回了另外一个函数,额外添加了一些功能。因为这样写实在不太优雅, [email

protected],下面代码等同于早期的写法。

def debug(func):

def wrapper():

print “[DEBUG]: enter {}()”.format(func.name)

return func()

return wrapper

@debug

def say_hello():

print “hello!”

这是最简单的装饰器,但是有一个问题,如果被装饰的函数需要传入参数,那么这个装饰器就坏了。因为返回的函数并不能接受参数,你可以指定装饰器函数 wrapper 接受和原函数一样的参数,比如:

def debug(func):

def wrapper(something): # 指定一毛一样的参数

print “[DEBUG]: enter {}()”.format(func.name)

return func(something)

return wrapper # 返回包装过函数

@debug

def say(something):

print “hello {}!”.format(something)

这样你就解决了一个问题,但又多了 N 个问题。因为函数有千千万,你只管你自己的函数,别人的函数参数是什么样子,鬼知道?还好 Python 提供了可变参数 * args 和关键字参数 ** kwargs ,有了这两个参数,装饰器就可以用于任意目标函数了。

def debug(func):

def wrapper(*args, **kwargs): # 指定宇宙无敌参数

print “[DEBUG]: enter {}()”.format(func.name)

print ‘Prepare and say…’,

return func(*args, **kwargs)

return wrapper # 返回

@debug

def say(something):

print “hello {}!”.format(something)

至此,你已完全掌握初级的装饰器写法。

高级一点的装饰器


带参数的装饰器和类装饰器属于进阶的内容。在理解这些装饰器之前,最好对函数的闭包和装饰器的接口约定有一定了解。(参见[http://betacat.online/posts/python-](

)

link.zhihu.com/?target=http%3A//betacat.online/posts/python- “http://betacat.online/posts/python-”) closure/)

带参数的装饰器


假设我们前文的装饰器需要完成的功能不仅仅是能在进入某个函数后打出 log 信息,而且还需指定 log 的级别,那么装饰器就会是这样的。

def logging(level):

def wrapper(func):

def inner_wrapper(*args, **kwargs):

print “[{level}]: enter function {func}()”.format(

level=level,

func=func.name)

return func(*a

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值