Python进阶(六)-python编写无参数decorator

举报
SHQ1874009 发表于 2020/12/30 02:03:46 2020/12/30
【摘要】 #Python进阶(六)-python编写无参数decorator   Python的 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。   使用 decorator 用Python提供的 @ 语法,这样可以避免手动编写 f = decorate(f) 这样的代码。   考察一个@log的定义: def log(f): def...

#Python进阶(六)-python编写无参数decorator
  Python的 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。
  使用 decorator 用Python提供的 @ 语法,这样可以避免手动编写 f = decorate(f) 这样的代码。
  考察一个@log的定义:

def log(f): def fn(x): print 'call ' + f.__name__ + '()...' return f(x) return fn

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

  对于阶乘函数,@log工作得很好:

@log
def factorial(n): return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)

  
 
  • 1
  • 2
  • 3
  • 4

  结果:
  call factorial()…
  3628800
  但是,对于参数不是一个的函数,调用将报错:

@log
def add(x, y): return x + y
print add(1, 2)

  
 
  • 1
  • 2
  • 3
  • 4

  结果:
  Traceback (most recent call last):
File “test.py”, line 15, in
print add(1,2)
  TypeError: fn() takes exactly 1 argument (2 given)
  因为 add() 函数需要传入两个参数,但是 @log 写死了只含一个参数的返回函数。
  要让 @log 自适应任何参数定义的函数,可以利用Python的 *args 和 **kw,保证任意个数的参数总是能正常调用:

def log(f): def fn(*args, **kw): print 'call ' + f.__name__ + '()...' return f(*args, **kw) return fn

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

  现在,对于任意函数,@log 都能正常工作。
##举例
  请编写一个@performance,它可以打印出函数调用的时间。
  计算函数调用的时间可以记录调用前后的当前时间戳,然后计算两个时间戳的差。
  参考代码:

import time
def performance(f): def fn(*args, **kw): t1 = time.time() r = f(*args, **kw) t2 = time.time() print 'call %s() in %fs' % (f.__name__, (t2 - t1)) return r return fn

@performance
def factorial(n): return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
![这里写图片描述](https://img-blog.csdnimg.cn/img_convert/46cc348062c27bf57424afe162b04ab4.png) ![这里写图片描述](https://img-blog.csdnimg.cn/img_convert/f9c024e20306fb0e4e3e84a15aab3217.png)

文章来源: shq5785.blog.csdn.net,作者:No Silver Bullet,版权归原作者所有,如需转载,请联系作者。

原文链接:shq5785.blog.csdn.net/article/details/62418756

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。