什么时候装饰一个功能,什么时候不装饰一个功能?

时间:2019-09-23 13:31:03

标签: python function decorator

我有一个装饰器,它记录脚本中存在的功能:

registry=[]

def register(func):
    print('running register(%s)' % func)
    registry.append(func)
    return func

然后我有一系列修饰的功能:

@register
def func1():
    print('running f1')

@register 
def func2():
    print('running f2')

运行脚本后,此方法有效,print(registry)返回:

[<function func1 at 0x0000000008433950>, <function func2 at 0x0000000008F06AE8>]

但是分别调用函数,例如:

func1()

仅返回'running f1':仅返回函数,不进行修饰。

我期望它返回类似'running register( func1) \n running func1'的内容。

所以我的问题是,当您有一个装饰函数并调用它时;何时会孤立调用函数,何时会调用修饰函数?

非常感谢。

2 个答案:

答案 0 :(得分:4)

您的register(装饰器)函数在解释代码时仅运行一次。

如果要更改功能行为,请尝试以下操作:

def register(func):
    registry.append(func)
    print('adding register(%s)' % func)

    def wrap(*args, **kwargs):
        print('running register(%s)' % func)
        return func(*args, **kwargs)

    return wrap

第一次打印完成一次,第二次打印在每次调用之前。 添加参数将使您的装饰器更加透明。

答案 1 :(得分:2)

我们所谓的“装饰器”只是a higher order function,而vue --version语法只不过是语法糖,所以:

@decorator

严格等同于

@decorate
def func():
    pass

正如Guillaume Deslandes提到的,如果此代码位于模块或脚本的顶级,则仅在运行时首次加载模块或脚本时才调用装饰器。

在您的情况下,装饰器函数def func(): pass func = decorate(func) 不变地返回其参数(应用于该函数的参数),因此调用“ decorated”函数将完全正确地工作,就像从未使用过一样。装饰。

如果要以任何方式修改修饰的函数(通过在原始函数之前或之后执行代码,或执行其他操作),则必须返回 new 函数,以“替换”原始函数(但是-通常-保留对原始函数的引用,以便此新的“包装器”函数仍可以调用原始函数),通常是在using the fact that Python functions are closure进行的:

register