python - How to use the `assigned` and `updated` parameters of functools.wraps? -
i know wraps has attributes below:
functools.wraps(wrapped[, assigned][, updated])
but want know how use assigned
, updated
params, have example?
the "assigned" parameter tells attributes on wrapper function assigned attributes of same name on wrapped (decorated) function. default '__module__', '__name__', '__doc__'
, defined default in variable functools.wrapper_assignments . @abarnet put in comments, 1 example of attribute 1 might want copy on function annotations in python 3.x- might want assigned parameter be: ('__module__', '__name__', '__doc__', '__anotations__')
.
the "updated" parameter more or less same, corresponding attributes in wrapper have it's "updated" method called attribute decorated function - means works when both attributes mutable mapping - example, dictionary. default update __dict__
attribute of wrapper __dict__
of wrapped, making wrapper function reflect extraneous attributes might have been assigned different underlying decorators (decorators applied before decorator call "wraps" applied). possible use cases changing "updated" change empty sequence, prevent __dict__
being updated. otherwise, if wanted update more attributes, mean working on project use different dictionary attributes on callable objects, , have more problems @ point not knowing how use "wraps" properly.
tl;dr: might find of use along:
@wraps(func, ('__module__', '__name__', '__doc__', '__anotations__'), ()) def wrapper(*args, **kw): ...
but not necessarily.
as final, anecdotal note, if decorated object instance of class __call__
method, instead of function, __dict__
update make wrapper function have copy of instance attributes of decorated instance - more side effect useful thing, these copied attributes won't follow further changes of state in decorated instance (and methods on decorated instance still receive "self" unwrapped instance):
>>> functools import wraps >>> class mycallable(object): ... def pr(self): ... print(self.a) ... def __call__(self, new_a): ... self.a = new_a >>> def deco(clb): ... @wraps(clb) ... def wrapper(*args): ... return clb(*args) ... return wrapper ... >>> m = mycallable() >>> m(1) >>> m.a 1 >>> m.pr() 1 >>> m = deco(m) >>> m(2) >>> m.a 1 >>> m.__wrapped__.pr() 2
so, might example of not wanting copy __dict__
over wrapper, , access orignal instance through __wrapped__
attribute, above. but, digress, had never seen wrapping instances of classes decorators, , can't think of usecase such not better resolved class method doing decorator should in first place.
Comments
Post a Comment