python_装饰器

闭包:

在一个外部函数中定义了一个内部函数,内部函数里运用了外部函数的临时变量,并且外部函数的返回值是内部函数的引用。这样就构成了一个闭包。

一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。

 1 def outer(x):  
 2     y=10
 3     def inner():
 4         print(x+y)
 5     return inner
 6 
 7 outer_func=outer(10)
 8 outer_func()
 9 
10 >>>20

 装饰器:

引用知乎上一段比喻:

  内裤可以用来遮羞,但是到了冬天它没法为我们防风御寒,聪明的人发明了长裤,有了长裤后的宝宝再也不冷了,装饰器就想我们这里说的长裤,在不影响内裤作用的前提下,为我们的身子提供保暖的功效。

 

装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。

装饰器示例:

    假如我们有一个函数,实现输出“hello world”的功能:

1 import time
2 def print_info():
3     print("-------------")
4     time.sleep(2)
5     print("Hello world")
6     print("-------------")
7 
8 
9 print_info()

 

  现在有个需求是需要统计上边函数的执行时间,最简单的做法是直接修改上边的函数,这么做的好处是能让自己被抄鱿鱼的时间缩短。那么一般小鸟会怎么做:

  把统计函数执行时间的功能再封装成一个函数,将需要被统计执行时间的函数当作参数传进去。函数即变量(知识点)

 1 import time
 2 def print_info():
 3     print("-------------")
 4     time.sleep(2)
 5     print("Hello world")
 6     print("-------------")
 7 
 8 def time_mode(func):
 9     StartTime=time.time()
10     func()
11     EndTime=time.time()
12     print("When the function is executed:%s m"%(EndTime- StartTime))
13 
14 time_mode(print_info)
15 
16 >>>-------------
17     Hello world
18     -------------
19     When the function is executed:2.0000147819519043 m

 

  当你欣喜若狂,自信满满,内心甚至还有些许小激动的拿给你领导过目,你清清嗓子准备念你早已准备好的获奖感言。没想到你领导面带微笑,和蔼可亲的递给你一个白眼,想让你好好体会一下。然后用尽量温柔的语气告诉你:“脑子其实是个好东西,你可以尝试拥有一下”

  你懊恼,你气愤,然后深吸一口气坐下来重新审视这段代码,才发现:我檫,这么写不是改变了人家原函数的调用方式了吗!尴尬,大写的尴尬 !然后你又重新提笔,写下下边一段代码:

 1 import time
 2 def print_info():
 3     print("-------------")
 4     time.sleep(2)
 5     print("Hello world")
 6     print("-------------")
 7 
 8 def wrapper(func):
 9     def time_mode():
10         StartTime=time.time()
11         func()
12         EndTime=time.time()
13         print("When the function is executed:%s m"%(EndTime- StartTime))
14     return time_mode
15 
16 print_info=wrapper(print_info)
17 print_info()
18 
19 >>>-------------
20     Hello world
21     -------------
22     When the function is executed:2.0003576278686523 m

 

你用高阶函数(知识点)似乎已经完成了想要的需求。但是每次执行都需要给源函数重新赋值。太繁琐,太low,主要是你猜想领导肯定会骂。怎么办,百度呀宝贝。经过百度你引进了魔法糖这个概念:

 1 import time
 2 
 3 def wrapper(func):
 4     def time_mode():
 5         StartTime=time.time()
 6         func()
 7         EndTime=time.time()
 8         print("When the function is executed:%s m"%(EndTime- StartTime))
 9     return time_mode
10 
11 @wrapper
12 def print_info():
13     print("-------------")
14     time.sleep(2)
15     print("Hello world")
16     print("-------------")
17 
18 print_info()
19 
20 >>>-------------
21     Hello world
22     -------------
23     When the function is executed:2.0005741119384766 m

 

牛逼,自信心一股脑的涌上了心头,你觉得你又可以秒天,秒地,秒空气了。然后你的思路像那什么一样开始不受控制,你就在想 这TM要是源函数要传参咋JB整?你开始了你的摸索、你的尝试:

 1 import time
 2 
 3 def wrapper(func):
 4     def time_medo(*args,**kwargs):
 5         StartTime = time.time()
 6         func(*args,**kwargs)
 7         EndTime=time.time()
 8         print("When the function is executed:%s m"%(EndTime- StartTime))
 9     return time_medo
10 
11 @wrapper
12 def Add(*args,**kwargs):
13     print("++++++++++")
14     time.sleep(1)
15     sums=0
16     for i in args:
17         sums+=i
18     print(sums)
19     print("++++++++++")
20 
21 Add(9,9,18,22)
22 
23 >>>++++++++++
24     58
25     ++++++++++
26     When the function is executed:1.0002260208129883 m    

完事儿,你嘿嘿一笑,深藏功与名!

posted @ 2018-04-07 18:13  叶小黑  阅读(168)  评论(0编辑  收藏  举报