• 如何为被装饰的函数保存元数据?


    需求:
    在函数对象中保存着一些函数的元数据,例如:
    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__',)
    
  • 相关阅读:
    macOS下查看端口是否被占用命令
    macOS下安装tomcat服务器
    unittest 知识问答题-也许面试会有用-欢迎补充
    python.unittest中常用断言方法
    如何在命令行terminal中运行pycharm项目
    如何保证 软件测试覆盖率
    如何衡量 测试覆盖率
    软件测试全流程 总结
    接口测试对传统测试模型的改进
    关于http/https协议
  • 原文地址:https://www.cnblogs.com/Richardo-M-Q/p/13957692.html
Copyright © 2020-2023  润新知