在将函数附加为对象属性的装饰器中使用 functools.partial

Mat*_*ing 4 python decorator

Python Cookbook9.5节中定义具有用户可调整属性的装饰器我在以下代码中使用 functools.partial 时遇到了困难:

# 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
Run Code Online (Sandbox Code Playgroud)

如果组合多个装饰器,它是否用于防止属性阴影?我不完全清楚为什么在这里使用部分,并希望得到任何澄清。

e.s*_*.s. 5

我会尝试两种解释。这是简短的。这些装饰器是等效的。

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
Run Code Online (Sandbox Code Playgroud)

这是长版。这是包装器功能的分步说明。

@attach_wrapper(wrapper)
def set_level(newlevel):
    level = newlevel
Run Code Online (Sandbox Code Playgroud)

相当于:

def set_level(newlevel):
   level = newlevel

set_level = attach_wrapper(wrapper)(set_level)
Run Code Online (Sandbox Code Playgroud)

首先,attach_wrapper(wrapper, func=None)返回一个带有一个参数的偏函数,func。为简单起见,我们称这个新函数为partial_attach。我们可以这样定义它:

def partial_attach(func):
    setattr(wrapper, func.__name__, func)
    return func
Run Code Online (Sandbox Code Playgroud)

attach_wrapper(wrapper, func=None)返回时partial_attach,我们有:

set_level = partial_attach(set_level)
Run Code Online (Sandbox Code Playgroud)

因为它返回set_level,set_level等于它自己。但现在wrapper有一个属性,set_level指向同一个函数。