装饰器浅谈

装饰器

如需转发,请注明出处:小婷儿的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

三、进阶

编写一个 decoratorwrapper),能在函数调用的前后打印出'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/

csdnhttps://blog.csdn.net/u010986753

 

OCP培训说明连接:https://mp.weixin.qq.com/s/2cymJ4xiBPtTaHu16HkiuA

OCM培训说明连接:https://mp.weixin.qq.com/s/7-R6Cz8RcJKduVv6YlAxJA

 

小婷儿的python正在成长中,其中还有很多不足之处,随着学习和工作的深入,会对以往的博客内容逐步改进和完善哒。

重要的事多做几遍。。。。。。

wpsED35.tmp 

posted @ 2019-01-13 09:18  小婷儿  阅读(239)  评论(0编辑  收藏  举报
levels of contents