鱼C论坛

 找回密码
 立即注册
查看: 4402|回复: 6

[技术交流] 深入理解装饰器(一)

[复制链接]
发表于 2018-9-28 19:26:56 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 RIXO 于 2019-5-9 19:38 编辑

装饰器是个什么东西呢?通俗点就是一个为了给函数添加功能的函数

实际开发过程中,需求经常有变化,所以我们得不停地改代码添加各种需要

那么有没有一种方法可以实现
1、不修改源代码
2、不修改调用方法
3、完成添加的功能

装饰器就是干这个的!

先从需求来讲,现在有一个函数如下
def func1():
     print('it's  func1 !!!')

为了给函数func1添加一个计时的功能,我们再写个函数
def  timeit():
     start = time.clock()
     func1()
     elpase = time.clock() - start
     print(elpase)

现在来看,我们为了实现这个功能,付出了什么代价
func1 的源代码没有改变,但是调用的方法改变了,我们需要写timeit()  而不是func1(),而且这个timeit的函数只能运用于func1这个函数,想给其他函数加功能得再重新写

所以,我们想解决通用性问题,可以所有想要这个功能的函数都直接实现,而不用重新写timeit的源代码
因为  函数是一个变量!
所以我们把需要这个功能的函数,当参数传入timeit函数中,实现这个功能
def timeit(every_func):
     start = time.clock()
     every_func()
     elpase = time.clock() - start
     print(elpase)

timeit(func1)  #把func1当作参数传入这个函数

然后再来想如何实现,不改变调用方式呢?
函数是一个变量!!
那么函数名是变量名,值又是什么呢?函数的值实际上就是函数在内存中的地址
so
我们把函数名重新赋值不就解决这个问题了吗?
func1 = timeit(func1)
然后再直接调用
func1()
不好意思,出错了,为什么呢?
因为在这个语句中func1 = timeit(func1),你直接调用了timeit函数  所以这里的赋值  实际上是把  timeit返回值(默认返回值为None)赋值给了func1
而None是不能调用的,所以会出错
快到达目标了,怎么能半途而废呢?所以我们接着改timeit函数
def timeit(every_func):
     start = time.clock()
     return every_func
     elpase = time.clock() - start
     print(elpase)
我们把timeit函数的返回值设置为传进去的函数内存地址,这样调用的时候,就解决问题了
but!!!     return会终止函数,下面的语句就没法执行了,所以,你又没有满足需求
所以再改
def timeit(every_func):
     def  wrapper():
           start = time.clock()
           every_func()
           elpase = time.clock() - start
           print(elpase)
     return  wrapper
这回我们在timeit函数里面又定义了一个函数,作用是什么呢,就是为了在满足需求的情况下,给timeit函数一个可以被调用的返回值(也就是wrapper函数的内存地址)
现在我们再来看看有没有满足需求
func1 = timeit(func1)      #把func1函数的内存地址传给timeit函数,然后返回一个内部函数wrapper内存地址赋值给func1
func1()         #调用wrapper函数,运行需要添加的功能和调用func1函数
完美,实现了三个功能,实际上一个简单的装饰器已经完成了
不过func1 = timeit(func1)看起来有点辣眼睛,所以我们写一个新的表示方法
@timeit     
def func1():
     print('it's  func1 !!!')
只要在任何函数前面加入@timeit就代表着  func1 = timeit(func1) 这个语句

初级装饰器,完成!下一篇帖子
深入理解装饰器(二)

评分

参与人数 2荣誉 +8 鱼币 +8 贡献 +6 收起 理由
zsc918877 + 3 + 3 + 3
nowtime + 5 + 5 + 3

查看全部评分

本帖被以下淘专辑推荐:

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

使用道具 举报

发表于 2018-9-29 11:46:47 | 显示全部楼层
-3
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-9-29 13:01:20 | 显示全部楼层
小甲鱼最近在做啥?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-9 11:03:06 | 显示全部楼层
-3
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-14 21:27:30 From FishC Mobile | 显示全部楼层
这个写的还能看懂点,其他关于装饰器的都看不太懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-2 19:55:30 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-8 22:55:55 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-28 18:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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