functools.wrapp和update wrapp的区别是什么

2024-09-28 18:57:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我无法找到这两个python函数之间的区别。

functools.wrapsupdate_wrapper

有人能给我一些代码示例吗,这样我就可以理解


Tags: 函数代码示例updatewrapperfunctools区别wraps
2条回答

functools.wraps相当于:

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

它实际上是使用partial而不是内部函数实现的,但是效果是一样的。

其目的是允许将其用作装饰:

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

相当于:

def g():
    ...
g = update_wrapper(g, f)

通常,您只需使用包装,它包装*update_wrapper*。更多:

  • partialing a function=创建一个新函数,其中一些参数绑定到值

  • 包装部分*用包装更新包装器*,从而为包装器

  • *update_wrapper*的目的是将某些属性(而不是参数)从wrapped复制到wrapper。默认为:

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

一个有用的例子:

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

相关问题 更多 >