• 装饰器浅谈


    装饰器

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

  • 相关阅读:
    【Spring】构建Spring Web应用
    【记录】Spring项目转化为Spring Web项目
    【生活工具】你能带我回家么,可能明天要下雨了。
    【Spring】面向切面之AOP
    【Spring】高级装配
    【Linux】Linux学习笔记(完结)
    【Spring】Spring的bean装配
    【Netty】源码分析目录
    【项目实战】多线程环境下正确创建单例
    【环境搭建】使用Jekyll搭建Github博客
  • 原文地址:https://www.cnblogs.com/pythonbao/p/10261902.html
Copyright © 2020-2023  润新知