装饰器作业
第一题自己做的:
1 #! /usr/bin/env python3 2 #-*- coding:utf-8 -*- 3 4 5 def log(text): 6 def decorator(func): 7 def wrapper(*args,**kw): 8 print('%s %s():'%(text,func.__name__)) 9 print('Begin Call'); 10 f = func(*args,**kw) 11 print('End Call') 12 return f 13 return wrapper 14 return decorator 15 16 @log('TestInfo') 17 def hello(): 18 print('Hello')
第二题,看到一个比较完整的就直接拿过来:
1 #闭包:参数和变量保存在内,返回函数本身;装饰器是函数的包装; 2 import functools #保存原函数的签名 3 import time 4 5 def log(text): 6 if isinstance(text,str): 7 #text 是 str 需要多执行一层 decorator 8 def decorator(func): 9 @functools.wraps(func) 10 def wrapper(*args,**kw): 11 p(text) 12 p('Action : %s()'%func.__name__) 13 tmp = func(*args,**kw) 14 p('Stop : %s()'%func.__name__) 15 return tmp 16 return wrapper 17 return decorator 18 else: 19 #text不是str,就是function 20 func = text 21 @functools.wraps(func) 22 def wrapper(*args,**kw): 23 start_time = time.time() 24 tmp = func(*args,**kw) 25 end_time = time.time() 26 p('No parameter,return Run-time:',end_time-start_time) 27 return tmp 28 return wrapper 29 30 @log 31 def function1() : 32 p(function1.__name__, 'is runing!') 33 return 'return function1()' 34 35 @log('Have a parameter') 36 def function2() : 37 p(function2.__name__, 'is runing!') 38 return 'return function2()' 39 40 p(function1()) 41 p(function2())
大体说说思路:
- 根据输入的参数的类型来判断所需要返回的装饰器层级
- 通过functools.wrapper来保留原函数的__name__
- 通过指向被装饰函数的临时变量来实现在被装饰函数执行前和执行后定位。最后返回临时变量即可。