Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the difference between functools.wraps and update_wrapper

Tags:

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

like image 258
user1865341 Avatar asked Mar 12 '13 09:03

user1865341


People also ask

What does wraps do in Functools?

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.

What is Functools?

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.

What is Functools Total_ordering?

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.

Is Functools part of standard library?

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 ).


2 Answers

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) 
like image 146
ecatmur Avatar answered Oct 08 '22 19:10

ecatmur


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 
like image 22
Roland Puntaier Avatar answered Oct 08 '22 17:10

Roland Puntaier