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)即可。

  • 相关阅读:
    (一〇八)iPad开发之横竖屏适配
    ZOJ 1414:Number Steps
    HDU 1391:Number Steps
    ZOJ 1871:Steps
    POJ 2590:Steps
    POJ 2629:Common permutation
    POJ 2562:Primary Arithmetic
    POJ 2505:A multiplication game
    HDU 1517:A Multiplication Game
    POJ 3650:The Seven Percent Solution
  • 原文地址:https://www.cnblogs.com/Mengchangxin/p/9248238.html
Copyright © 2011-2022 走看看