In Python Cookbook section 9.5. Defining a Decorator with User Adjustable Attributes I've been having difficulty wrapping my head around the use of functools.partial in the following code:
# Utility decorator to attach a function as an attribute of obj
def attach_wrapper(obj, func=None):
if func is None:
return partial(attach_wrapper, obj)
setattr(obj, func.__name__, func)
return func
Is its use to prevent shadowing of attributes if composing multiple decorators? I am not totally clear to why partial would be used here and would appreciate any clarification.
I'll try two explanations. Here's the short one. These decorators are equivalent.
def attach_wrapper(obj, func=None):
if func is None:
return partial(attach_wrapper, obj)
setattr(obj, func.__name__, func)
return func
def my_attach_wrapper(obj):
def wrapper(func):
setattr(obj, func.__name__, func)
return func
return wrapper
And here's the long version. This is a step-by-step of what the wrapper does.
@attach_wrapper(wrapper)
def set_level(newlevel):
level = newlevel
is equivalent to:
def set_level(newlevel):
level = newlevel
set_level = attach_wrapper(wrapper)(set_level)
first, attach_wrapper(wrapper, func=None)
returns a partial function that takes one argument, func
. for simplicity, let's call this new function partial_attach
. And we can define it like so:
def partial_attach(func):
setattr(wrapper, func.__name__, func)
return func
when attach_wrapper(wrapper, func=None)
returns partial_attach
, we have:
set_level = partial_attach(set_level)
since that returns set_level
, set_level
is equal to itself. But now wrapper
has an attribute, set_level
, which points to the same function.
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