zoukankan      html  css  js  c++  java
  • 如何为被装饰的函数保存元数据?

    需求:
    在函数对象中保存着一些函数的元数据,例如:
    f.name:函数的名字
    f.doc:函数文档字符串
    f.module:函数所属模块名
    f.dict:函数的属性字典
    f.defaults:默认参数元组
    .....
    我们在使用装饰器后,再访问上面这些属性访问时,看到的是内部包裹函数的元数据,原来函数的元数据便丢失了,应该如何解决 ?

    思路:
    使用标准库中的funtools中的装饰器wraps装饰内部包裹函数,可以制定将原函数的某些属性,更新到包裹函数上面

    代码:

    from functools import update_wrapper,wraps
    
    def my_decorator(func):
        @wraps(func) # 等价于update_wrapper(wrap,func)
        def wrap(*args,**kwargs):
            '''某种功能包裹函数'''
            # 此处实现某种功能
            # ...
    
            return func(*args,**kwargs)
        # update_wrapper(wrap,func)
        return wrap
    
    @my_decorator
    def xxx_func(a,b):
        '''
        xxx_func函数文档
        ...
        '''
        pass
    
    print(xxx_func.__name__)
    print(xxx_func.__doc__)
    
    =========================================
    
    >>> def f():
    ...     '''fuction f'''
    ...     pass
    ... 
    ... f.__name__
    ... f.__name__
    ... print(f.__name__)
    ... f.__module__
    ... 
    ... 
    f
    '__main__'
    >>> 
    >>> def f():
    ...     '''function f'''
    ...     pass
    ... 
    ... 
    >>> f.__name__
    'f'
    >>> f.__module__
    '__main__'
    >>> from random import randint
    >>> randint.__module__
    'random'
    >>> f.__doc__
    'function f'
    >>> f?
    Signature: f()
    Docstring: function f
    File:      ~/python_study/<ipython-input-3-a10bb6a09581>
    Type:      function
    >>> def f(a:int,b:int) -> int:
    ...     pass
    ... 
    ... 
    >>> f.__annotations__
    {'a': <class 'int'>, 'b': <class 'int'>, 'return': <class 'int'>}
    >>> def f(a,b=1,c=[]):
    ...     pass
    ... 
    ... 
    >>> f.__defaults__
    (1, [])
    >>> def f(a): # 闭包
    ...     return lambda n: a ** n
    ... 
    ... 
    >>> g = f(3)
    >>> g(4)
    81
    >>> g.__closure__
    (<cell at 0x7f7002d9be28: int object at 0x559184504360>,)
    >>> c = g.__closure__[0]
    >>> c.cell_contents
    3
    >>> from functools import WRAPPER_ASSIGNMENTS
    >>> WRAPPER_ASSIGNMENTS
    ('__module__', '__name__', '__qualname__', '__doc__', '__annotations__')
    >>> from functools import WRAPPER_UPDATES
    >>> WRAPPER_UPDATES
    ('__dict__',)
    
  • 相关阅读:
    文档_word常用设置-操作
    Java NIO总结 整理
    Spring缓存注解@Cacheable、@CacheEvict、@CachePut使用
    Lock和synchronized比较详解
    SpringBoot如何将类中属性与配置文件中的配置进行绑定
    简述MyBatis的一级缓存、二级缓存原理
    服务器端filter解决ajax简单请求跨域访问问题
    Spring Boot异步执行程序
    程序猿和hr面试时的巅峰对决
    数据库三大范式详解(通俗易懂)
  • 原文地址:https://www.cnblogs.com/Richardo-M-Q/p/13957692.html
Copyright © 2011-2022 走看看