| 
 | 
 
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册  
 
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) 这个语句 
 
初级装饰器,完成!下一篇帖子 
深入理解装饰器(二) 
 
 |   
 
评分
- 
查看全部评分
 
 
 
 
 
 |