今天看了道面试题,发现对python的装饰器的理解实在太浅,故看了些帖子
写了点笔记,以备不时之需。务必使用debug方法逐步看的执行顺序
v1.0计算一个函数的耗时
import time
def func_sum():
sum = 1+ 1
print (sum)
def func_time(func):
start = time.time()
func()
end =time.time()
print("time used:", end - start)
func_time(func_sum)
通过func_time(func_sum)函数记录func_sum求和函数前后的时间戳,获取func_sum的运算时间,简单运算太快了结果应该是0,可以在func()给一个time.sleep(5),5秒延迟。
v2.0装饰器计算函数的时间
import time
def out_time(func):
def test():
start = time.time()
func()
end = time.time()
print("time used:", end - start)
return test
@out_time
def func_sum():
sum = 1 + 1
print(sum)
func_sum()
v1.0如果需要计算其他函数通过修改func_time()括号内的函数名称计算时间。
v2.0装饰器只需在函数前添加@out_time,调用时间函数即可。
这或许是装饰器的优点之一吧
下面说一些简单的装饰器,参考了一些写的
v1.1无参简易装饰器
def outer(func):
print('A')
def inter():
print('B')
func()
print('C')
return inter
@outer # func = outer(func)
def func():
print('D')
func()
通过函数运行结果A B D C可以看出执行的顺序,再配合是pycharm的debug功能
先执行@outer装饰器,outer()函数得到一个A和函数的对象inter,
inter和inter()是不一样的,inter只是一个对象,并不会运行,
然后当运行到func()的时候,相当于给了inter执行的参数,
然后inter会print B,func() print D,inter 执行print C 。
v2.1传参简易装饰器
def out(func):
print(1)
def int(*args, **kwargs):
print(2)
func(*args, **kwargs)
print(3)
return int
@out # func_sum = out(func_sum)
def func_sum(a, b):
sum = a + b
print(sum)
func_sum('x', 'w')
结果是
1
2
xw
3
*后面是元祖 (,) 上面例子将参数(‘x’,‘w’)传入函数运算得xw
**后面跟的是字典格式 {},如 {‘a’:1}
v3.1多个简易装饰器
def out_1st(func):
print('hello')
def int_1st():
print('first_11111')
func()
print('first_22222')
return int_1st
def out_2nd(func):
print('world')
def int_2nd():
print('second_11111')
func()
print('second_22222')
return int_2nd
@out_1st
@out_2nd
def func_str():
print('=' * 20)
func_str()
@装饰器自下而上获取两个对象,赋予func_str参数时从上往下运行…(Debug单步运行更直观)
多个装饰器装饰一个函数,一环套一环
上面代码
@out_1st #(first_)
@out_2nd #(second_)
结果为
若换顺序
@out_2nd #(second_)
@out_1st #(first_)
结果为