I am not able to find what is the difference between these two python functions.
functools.wraps
and update_wrapper
Can some give me some code example so that i can understand what is the difference
wraps() is a decorator that is applied to the wrapper function of a decorator. It updates the wrapper function to look like wrapped function by copying attributes such as __name__, __doc__ (the docstring), etc. Parameters: wrapped: The function name that is to be decorated by wrapper function.
Functools module is for higher-order functions that work on other functions. It provides functions for working with other functions and callable objects to use or extend them without completely rewriting them.
Python Functools – total_ordering() Functools module in python helps in implementing higher-order functions. Higher-order functions are dependent functions that call other functions. Total_ordering provides rich class comparison methods that help in comparing classes without explicitly defining a function for it.
The functools module, part of Python's standard Library, provides useful features that make it easier to work with high order functions (a function that returns a function or takes another function as an argument ).
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)
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With