what is the difference between functools.wraps and update_wrapper

前端 未结 2 760
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-04 01:31

I am not able to find what is the difference between these two python functions.

functools.wraps and update_wrapper

Can some give me

相关标签:
2条回答
  • 2021-02-04 02:04

    Normally you will just use wraps, which wraps *update_wrapper* . More:

    • partial ing a function = create a new function with some arguments bound to values

    • wraps partials *update_wrapper* with wrapped, thus creating a decorator for wrapper

    • *update_wrapper* 's purpose is to copy certain attributes (not arguments) from wrapped to wrapper. On default these are:

    WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__',
                           '__annotations__')
    WRAPPER_UPDATES = ('__dict__',)
    

    A useful example:

    try:
        from itertools import izip_longest as zip_longest
    except:
        from itertools import zip_longest
    from collections import Iterable
    from functools import wraps
    
    def ziplongest(*args):
        '''zip_longest with last element as filler
        >>> args=([9],[2,3],1)
        >>> [t for t in ziplongest(*args)]
        [(9, 2, 1), (9, 3, 1)]
    
        '''
        iterable = lambda a:(a if isinstance(a,Iterable) else [a])
        _args = [iterable(a) for a in args]
        withnone = zip_longest(*_args)
        for e in withnone:
            yield tuple((en or _args[i][-1]) for i,en in enumerate(e))
    
    def listable(f):
        '''apply f to list members
        >>> @listable
        ... def mul(a,b):
        ...     'returns a*b'
        ...     return a*b
        >>> mul(2,[3,9])
        [6, 18]
        >>> mul.__doc__
        'returns a*b'
    
        '''
        @wraps(f)#without this e.g __doc__ would get hidden
        def to_elems(*args,**kwargs):
            if any(isinstance(x,list) for x in args):
                return [f(*a,**kwargs) for a in ziplongest(*args)]
            else:
                return f(*args,**kwargs)
        return to_elems
    
    0 讨论(0)
  • 2021-02-04 02:21

    functools.wraps is equivalent to:

    def wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES):
        def decorator(wrapper):
            return update_wrapper(wrapper, wrapped=wrapped, ...)
        return decorator
    

    It's actually implemented using partial instead of an inner function, but the effect is the same.

    The purpose is to allow using it as a decorator:

     @wraps(f)
     def g():
         ...
    

    is equivalent to:

    def g():
        ...
    g = update_wrapper(g, f)
    
    0 讨论(0)
提交回复
热议问题