zoukankan      html  css  js  c++  java
  • 装饰器补充知识点_ @functools.wraps(func)

     1 # -*- coding: utf-8 -*-
     2 
     3 def log(func):
     4     def wrapper(*args,**kwargs):
     5         print('这个函数是 %s()'%func.__name__)
     6         return func(*args,**kwargs)
     7          
     8     return wrapper
     9 # import functools
    10 # def log(text):
    11 #     def decorator(func):
    12 #         @functools.wraps(func)
    13 #         def wrapper(*args, **kw):
    14 #             #wrapper.__name__ = func.__name__
    15 #             print('%s 这个函数是 %s():' % (text, func.__name__))
    16 #             
    17 #             return func(*args, **kw)
    18 #         return wrapper
    19 #     return decorator
    20 
    21 # @log('hello')  #now=log('hello')(now)
    22 @log
    23 def now():
    24     print('2018-06-30')
    25     return 1
    26     
    27 print(now())
    28 print(now.__name__)

    结果:

    这个函数是 now()
    2018-06-30
    1
    wrapper

    以上两种decorator的定义都没有问题,但还差最后一步。因为我们讲了函数也是对象,它有__name__等属性,但你去看经过decorator装饰之后的函数,它们的__name__已经从原来的'now'变成了'wrapper'

    因为返回的那个wrapper()函数名字就是'wrapper',所以,需要把原始函数的__name__等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错。

    # -*- coding: utf-8 -*-
    
    def log(func):
        def wrapper(*args,**kwargs):
            wrapper.__name__ = func.__name__
            print('这个函数是 %s()'%func.__name__)
            return func(*args,**kwargs)
             
        return wrapper
    
    @log
    def now():
        print('2018-06-30')
        return 1
        
    print(now())
    print(now.__name__)

    结果:

    这个函数是 now()
    2018-06-30
    1
    now

    不需要编写wrapper.__name__ = func.__name__这样的代码,Python内置的functools.wraps就是干这个事的,所以,一个完整的decorator的写法如下:

     1 # -*- coding: utf-8 -*-
     2 import functools
     3 def log(func):
     4     @functools.wraps(func)
     5     def wrapper(*args,**kwargs):
     6 #         wrapper.__name__ = func.__name__
     7         print('这个函数是 %s()'%func.__name__)
     8         return func(*args,**kwargs)
     9          
    10     return wrapper
    11 
    12 @log
    13 def now():
    14     print('2018-06-30')
    15     return 1
    16     
    17 print(now())
    18 print(now.__name__)

    结果:

    这个函数是 now()
    2018-06-30
    1
    now

    import functools是导入functools模块。模块的概念稍候讲解。现在,只需记住在定义wrapper()的前面加上@functools.wraps(func)即可。

  • 相关阅读:
    正则表达式
    js trim函数 去空格函数与正则集锦
    变量的作用域问题
    for...in 语句
    JS小案例分析
    JS动态创建元素的方式
    JS类的封装
    js操作节点小结
    节点兼容
    节点小结
  • 原文地址:https://www.cnblogs.com/Mengchangxin/p/9248238.html
Copyright © 2011-2022 走看看