函数何时被修饰,函数何时不被修饰?

2024-04-25 22:56:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个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'的内容。你知道吗

所以我的问题是,当你有一个修饰函数并调用它时,它什么时候会单独调用这个函数,什么时候会调用修饰函数?你知道吗

非常感谢。你知道吗


Tags: 函数脚本registerdef记录functiondecoratorrunning
1条回答
网友
1楼 · 发布于 2024-04-25 22:56:03

我们称之为“decorator”的只是a higher order function,而@decorator语法只不过是语法糖,所以:

@decorate
def func():
    pass

严格等同于

def func():
    pass

func = decorate(func)

正如GuillaumeDeslandes所提到的,如果此代码位于模块或脚本的顶层,则仅当运行时首次加载模块或脚本时才会调用decorator。你知道吗

在您的例子中,decorator函数register返回它的参数(应用它的函数)不变,因此调用“decorated”函数将像从未被修饰过一样工作。你知道吗

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

def decorate(fun):
   def wrapper(*args, **kw):
       res = fun(*args, **kw)
       print("function {} called with *{}, *{} returned {}".format(fun, args, kw, res)
       return res

   return wrapper



@decorate
def fun(a):
    return a * 2
网友
2楼 · 发布于 2024-04-25 22:56:03

在解释代码时,register(decorator)函数只运行一次。你知道吗

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

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

第一次打印完成一次,第二次打印在每次调用前完成。 添加参数将使decorator更加透明。你知道吗

相关问题 更多 >