鱼C论坛

 找回密码
 立即注册
查看: 2999|回复: 8

[技术交流] python装饰器通俗易懂的解释

[复制链接]
发表于 2016-2-18 14:35:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了。总结了一下解释得比较好的,通俗易懂的来说明一下:
小P闲来无事,随便翻看自己以前写的一些函数,忽然对一个最最最基础的函数起了兴趣:
1 def sum1:
2      sum = 1 + 2
3      print(sum)
4 sum1
此时小P想看看这个函数执行用了多长时间,所以写了几句代码插进去了:
1 import time
2
3 def sum1:
4     start = time.clock
5     sum = 1+2
6     print(sum)
7     end = time.clock
8     print("time used:",end - start)
9
10 sum1
运行之后,完美~~
可是随着继续翻看,小P对越来越多的函数感兴趣了,都想看下他们的运行时间如何,难道要一个一个的去改函数吗?当然不是!我们可以考虑重新定义一个函数timeit,将sum1的引用传递给他,然后在timeit中调用sum1并进行计时,这样,我们就达到了不改动sum1定义的目的,而且,不论小P看了多少个函数,我们都不用去修改函数定义了!
import time

def sum1:
    sum = 1+ 2
    print (sum)

def timeit(func):
    start = time.clock
    func
    end =time.clock
    print("time used:", end - start)

timeit(sum1)
咂一看,没啥问题,可以运行!但是还是修改了一部分代码,把sum1 改成了timeit(sum1)。这样的话,如果sum1在N处都被调用了,你就不得不去修改这N处的代码。所以,我们就需要杨sum1具有和timeit(sum1)一样的效果,于是将timeit赋值给sum1。可是timeit是有参数的,所以需要找个方法去统一参数,将timeit(sum1)的返回值(计算运行时间的函数)赋值给sum1。
1 import time
2
3 def sum1:
4     sum = 1+ 2
5     print (sum)
6
7 def timeit(func):
8     def test:
9         start = time.clock
10         func
11         end =time.clock
12         print("time used:", end - start)
13     return test
14
15 sum1 = timeit(sum1)
16 sum1
这样一个简易的装饰器就做好了,我们只需要在定义sum1以后调用sum1之前,加上sum1= timeit(sum1),就可以达到计时的目的,这也就是装饰器的概念,看起来像是sum1被timeit装饰了!Python于是提供了一个语法糖来降低字符输入量。
1 import time
2   
3 def timeit(func):
4      def test:
5 start = time.clock
6          func
7 end =time.clock
8 print("time used:", end - start)
9      return test
10  
11 @timeit
12 def sum1:
13      sum = 1+ 2
14      print (sum)
15
16  sum1
重点关注第11行的@timeit,在定义上加上这一行与另外写sum1 = timeit(sum1)完全等价。

评分

参与人数 2荣誉 +5 鱼币 +10 贡献 +3 收起 理由
RIXO + 5 + 5 + 3
SixPy + 5 热爱鱼C^_^

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-2-18 17:06:45 | 显示全部楼层
好东西~~收藏了~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-18 14:05:11 | 显示全部楼层
很好解释了为什么要有装饰器的原因。赞一个!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-2 10:05:08 | 显示全部楼层
我试了一下 为什么只能看到timeit()函数的结果  看不到sum1()的结果呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-24 09:36:41 | 显示全部楼层
好东西~~收藏了~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-2 16:33:04 | 显示全部楼层
comeonhcl 发表于 2016-9-2 10:05
我试了一下 为什么只能看到timeit()函数的结果  看不到sum1()的结果呢?

为什么看不到sum1()的结果呢?大佬有头绪了吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-2 23:27:13 | 显示全部楼层
hkjianvchf0 发表于 2018-8-2 16:33
为什么看不到sum1()的结果呢?大佬有头绪了吗?

搞懂了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-10 10:42:52 | 显示全部楼层
哇,这个易懂多了感谢楼主~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-12 22:00:38 | 显示全部楼层
没想到还有这种好东西,比无良的小甲鱼写的文档,容易懂多了!!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-23 02:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表