意外遇到python decorator的一个奇怪问题,基本上当我直接调用decorator函数时,被包装的原始函数被包装了两次。
一些简单的代码来显示问题:
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
预期两个命令之间的结果相同,但后一个命令似乎将原始函数包装了两次。当我在没有括号的情况下运行这两个命令时,它们都正确地指向包装器函数,但使用括号执行后的结果不同。
我用以下逻辑说服了自己,但仍然感到不舒服,所以我正在寻找对我的想法的评论或纠正:
命令1(:调用original_func->my_deco->包装器->包装+original_func执行
命令2(:调用my_deco->包装器->包装+original_func执行(它是包装版本(
因此,看起来命令1(中的original_func保持为"0";原始的";无包装;并且命令2中的original_func(是"0";"包裹";版本
提前谢谢。
当你定义original_func
时,你使用了一个decorator,所以python对它进行了包装。在命令2中,你自己再次包装它,所以结果是函数被包装了两次
如果运行以下操作,输出应该是正确的:
def original_func(text):
print (f'original func print {text}')
my_deco(original_func)('hello')
这里有一个简单的例子:
创建装饰器:
def decor(func):
def wrapper(num1, num2):
print('before')
func(num1, num2)
print('after')
return wrapper
调用decorator。此代码不正确,因为您调用了decorator两次,即@decorat和decorat(add(:
@decor
def add(num1, num2):
print(num1 + num2)
add = decor(add) ## This line will cause it to print a second time. Remove it.
add(3, 88)
调用decorator。此代码正确:
@decor
def add(num1, num2):
print(num1 + num2)
add(3, 88)