python装饰器简单理解

装饰器定义:1、把一个函数名当作实参传给另外一个函数(在不修改装饰函数源代码的情况下为其添加功能)  

      2、返回值中包含函数名(不改变函数调用方式)

源代码:

1 def f():
2     def f():
3     time.sleep(2)
4     print('i am f') 
5     

加基本计算程序运行时间函数

1 def f():
2     print('i am f')
3     time.sleep(2)
4 def my_time():
5             s_time = time.time()
6             f()
7             e_time = time.time()
8             print("消耗了%s秒"%(e_time - s_time))
9 my_time()
 1 #把func函数传入
 2 def f():
 3     print('i am f')
 4     time.sleep(2)
 5 def my_time(func): #传入函数
 6             s_time = time.time()
 7             f()    #打印函数
 8             e_time = time.time()
 9             print("%s消耗了%s秒"%(func.__name__,e_time - s_time))
10 my_time(f)  #

但调用时需用my_time来调用,而不能修改调用方式,思路就是可以把my_time下的定义为一个函数,再把它返回(return wrapper) 1 def f():

 1 import time
 2 def f():
 3         print('i am f')
 4         time.sleep(2)
 5 def my_time(func): #传入函数 my_timer(f) func = f
 6     def wrapper():
 7             s_time = time.time()
 8             #f()    #打印函数 代码错了啊,这里应该要改为func(),
 9             func()
10             e_time = time.time()
11             print("%s消耗了%s秒"%(func.__name__,e_time - s_time))
12     return  wrapper #返回这个函数的内存地址
13 n = my_time(f) #相当于执行my_time函数,该函数返回指向了wrapper,相当于执行了wrapper(),而wrapper就开始执行时间啊,打印这些
14 f = n
15 f()

 

理解上述的return wrapper:返回的是func的内存,即 f函数的内存地址

print(my_time(f)) 输出的是wrapper的内存地址 表示return返回的地址

定义一个外函数,让内函数进行返回 所以就有 外return,外return的是这个函数的返回值,而不是函数运行结果 

@my_time #等价于f = my_time(f)

加要求,添加一个log函数,且要在时间函数前

 

 1 import time
 2 def log(func):
 3     def wrapper():
 4         print('it is a log')
 5         func()
 6         #把函数执行结果返回,不然不会运行my_time里函数
 7     return  wrapper #
 8 def my_time(func):
 9     def wrapper():
10         s_time = time.time()
11         func()
12         e_time = time.time()
13         print('耗时:%s'%(e_time - s_time))
14     return  wrapper
15 @log
16 @my_time
17 def f():
18     time.sleep(2)
19     print('i am f')
20 f()

 

函数是从里到外装

如果源代码有return值

 1 def my_time(func):
 2     def wrapper():
 3         s_time = time.time()
 4         func()
 5         e_time = time.time()
 6         print('耗时:%s'%(e_time - s_time))
 7     return  wrapper
 8 @my_time
 9 def f():
10     time.sleep(2)
11     return('i am f')
12 n = f()
13 print(n)
14 
15 #output:
16 耗时:2.001243829727173
17 None

 

改进:

 

 1 def my_time(func):
 2     def wrapper():
 3         s_time = time.time()
 4         temp = func()
 5         e_time = time.time()
 6         print('耗时:%s'%(e_time - s_time))
 7         return temp #
 8     return  wrapper
 9 @my_time
10 def f():
11     time.sleep(2)
12     return('i am f')
13 n = f()
14 print('n =',n)
output:

耗时:2.000271797180176
n = i am f

能看到就是多了一个内return,return做的是把返回值带入原函数加返回值的话,return func()就是把func()的返回值返回

就要在打印时也要把返回值打印出来,所以就有了内return 只是把返回值return 

源程序带有一个或多个参数

 1 def my_time(func):
 2     def wrapper(*args,**kwargs):
 3         s_time = time.time()
 4         temp = func(*args,**kwargs)
 5         e_time = time.time()
 6         print('耗时:%s'%(e_time - s_time))
 7         return temp
 8     return  wrapper
 9 @my_time
10 def f(x,y):
11     return x,y
12 n = f('大哥','是我') #
13 print('n =',n)

这样输入带有参数的,就会正常返回多个参数

 

posted @ 2019-01-10 15:18  章十慕珊·  阅读(203)  评论(0)    收藏  举报