装饰器浅谈
装饰器
如需转发,请注明出处:小婷儿的python https://www.cnblogs.com/xxtalhr/p/10261902.html
有问题请在博客下留言或加作者微信:tinghai87605025 或 QQ :87605025
python QQ交流群:py_data 483766429
一、概念
l 装饰器其实就是一个以函数作为参数并返回一个替换函数的可执行函数(注:与闭包类似,参数是函数);
l wrapper()函数的参数定义是(*args, **kw),因此,wrapper()函数可以接受任意参数的调用。在 wrapper()函数内,首先打印日志,再紧接着调用原始函数;
二、练习
import time import functools def add(): print('调用(add)函数时间:%s' % time.strftime('%Y-%m-%d %H:%M:%S')) print('add=============')
结果:
add=============
# 装饰器函数 # 方法一:打印每一个函数调用时间 def log(func): def wrapper(): # __name__可以获得函数名称 print('调用%s函数时间:%s' % (func.__name__, time.strftime('%Y-%m-%d %H:%M:%S'))) func() return wrapper add_wrap = log(add) add_wrap() print('log=============')
结果:
调用add函数时间:2019-01-13 18:02:27
调用(add)函数时间:2019-01-13 18:02:27
log=============
1 # 方法一,每次写都要print('调用%s函数时间:%s'%(func.__name__, time.strftime('%Y-%m-%d %H:%M:%S'))) 2 # 方法二:打印每一个函数调用时间 3 def mul(): 4 print('mul') 5 mul_wrap = log(mul) 6 mul_wrap() 7 # add不是原来的add函数了,只是名字相同 8 add = log(add) 9 add() 10 print('mul=============')
结果:
调用mul函数时间:2019-01-13 18:02:27
mul
调用add函数时间:2019-01-13 18:02:27
调用(add)函数时间:2019-01-13 18:02:27
mul=============
1 # 方法三:借助@的语法,将装饰器作用到指定的函数 2 @log # sub = log(sub) 3 def sub(): 4 print('sub') 5 sub() 6 print('===============')
结果:
调用sub函数时间:2019-01-13 18:02:27
sub
===============
1 # 方法四:带参数装饰器 2 def divide_function(funct): 3 def wrap(*kwargs, **kw): # 可以传任一参数 4 print('调用%s函数时间:%s' % (funct.__name__, time.strftime('%Y-%m-%d %H:%M:%S'))) 5 print('实际应用中,大多时候只改变print部分,其他都不变') 6 return funct(*kwargs, **kw) # 原始函数有返回值,所以return,若没有就返回none 7 8 return wrap 9 @divide_function 10 def power_function(a, b): 11 return a**b 12 f = power_function(2, 3) 13 print('调用函数:%s,f:%s'%(power_function.__name__,f))
结果:
调用power_function函数时间:2019-01-13 18:02:27
实际应用中,大多时候只改变print部分,其他都不变
调用函数:wrap,f:8
1 # 方法五:functools 2 def divide_function(funct): 3 @functools.wraps(funct)#作用:wrapper.__name__ = func.__name__ 4 def wrap(*kwargs, **kw): # 可以传任一参数 5 print('调用%s函数时间:%s' % (funct.__name__, time.strftime('%Y-%m-%d %H:%M:%S'))) 6 print('实际应用中,大多时候只改变print部分,其他都不变') 7 return funct(*kwargs, **kw) # 原始函数有返回值,所以return,若没有就返回none 8 9 return wrap 10 @divide_function 11 def power_function(a, b): 12 return a**b 13 f = power_function(2, 3) 14 print('调用函数:%s,f:%s'%(power_function.__name__,f))
结果:
调用power_function函数时间:2019-01-13 18:02:27
实际应用中,大多时候只改变print部分,其他都不变
调用函数:power_function,f:8
三、进阶
编写一个 decorator(wrapper),能在函数调用的前后打印出'begin call'和'end call'的日志。
1 import functools 2 3 def log(func): 4 @functools.wraps(func) 5 def wrapper(*args, **kw): 6 print('call %s():' % func.__name__) 7 return func(*args, **kw) 8 return wrapper 9 10 @log 11 def now(): 12 print('2019-01-13') 13 14 now() 15 16 def logger(text): 17 def decorator(func): 18 @functools.wraps(func) 19 def wrapper(*args, **kw): 20 print('%s %s():' % (text, func.__name__)) 21 return func(*args, **kw) 22 return wrapper 23 return decorator 24 25 @logger('DEBUG') 26 def today(): 27 print('2019-01-13') 28 29 today() 30 print(today.__name__)
结果:
call now():
2019-01-13
DEBUG today():
2019-01-13
today
欢迎关注小婷儿的博客:
博客园:http://www.cnblogs.com/xxtalhr/
csdn:https://blog.csdn.net/u010986753
OCP培训说明连接:https://mp.weixin.qq.com/s/2cymJ4xiBPtTaHu16HkiuA
OCM培训说明连接:https://mp.weixin.qq.com/s/7-R6Cz8RcJKduVv6YlAxJA
小婷儿的python正在成长中,其中还有很多不足之处,随着学习和工作的深入,会对以往的博客内容逐步改进和完善哒。
重要的事多做几遍。。。。。。
文章内容来源于小婷儿的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解 有趣的事,Python永远不会缺席!
如需转发,请注明出处:小婷儿的博客python https://www.cnblogs.com/xxtalhr/
博客园:https://www.cnblogs.com/xxtalhr/
CSDN:https://blog.csdn.net/u010986753
有问题请在博客下留言或加作者:
微信:tinghai87605025
QQ :87605025
python QQ交流群:py_data 483766429
培训说明:
OCP培训说明连接:https://mp.weixin.qq.com/s/2cymJ4xiBPtTaHu16HkiuA
OCM培训说明连接:https://mp.weixin.qq.com/s/7-R6Cz8RcJKduVv6YlAxJA
小婷儿的python正在成长中,其中还有很多不足之处,随着学习和工作的深入,会对以往的博客内容逐步改进和完善哒。重要的事多说几遍。。。。。。