python 装饰器包装两次?

python decorator wraps twice?

偶然遇到python装饰器的奇怪问题,基本上我直接调用装饰器函数时,原来被包裹的函数被包裹了两次。

一些简单的代码来说明问题:

def my_deco(f):
    def wrapper(*args):
        print('some code before')
        f(*args)
        print('some code after')
    return wrapper

@my_deco
def original_func(text):
    print   (f'original func print {text}')

然后命令 1):

original_func('hello')

将打印(顺便说一下,这是正确的):

some code before
original func print hello
some code after

但是命令 2):

my_deco(original_func)('hello')

将打印如下:

some code before
some code before
original func print hello
some code after
some code after

原以为两个命令的结果相同,但后一个命令似乎将原始函数包装了两次。当我 运行 两个命令都没有括号时,它们都正确地指向包装函数,但是一旦用括号执行,结果就不同了。

我有点用下面的逻辑说服了自己,但仍然感到不舒服,所以我正在寻找对我的想法的评论或纠正:

command 1): call original_func -> my_deco -> wrapper -> wrapping + original_func execution

command 2): call my_deco -> wrapper -> wrapping + original_func 执行(是wrapped版本)

所以看起来命令 1) 中的 original_func 仍然是“原始的”,没有换行;命令 2) 中的 original_func 是“包装”版本。

提前致谢。

当您定义 original_func 时,您使用了装饰器,因此 python 包装了它。在命令 2) 中,您自己再次包装了它,因此结果是函数被包装了两次。
如果你 运行 以下,输出应该是正确的:

def original_func(text):
    print   (f'original func print {text}')

my_deco(original_func)('hello')