我正在尝试学习 python 中的闭包和装饰器。
我知道,在我下面的代码中,变量 fn 已被分配给一个“单元格”对象,它本身将引用函数对象
my_func
一旦它作为参数传递给函数“外部”并调用外部。
我不明白为什么当从函数
fn
(装饰函数)中调用inner
时,它调用inner
(即装饰函数)而不是“原始”未装饰的my_func函数(这是什么作为参数传递给“外部”)
我没想到装饰
my_func
会导致我上面提到的单元格现在引用my_func
的“不同版本”,它从控制台输出中显示的就是发生的事情。
因此我对下面的代码有两个问题:
my_func = outer(my_func)
中,作业左侧的“my_func”是什么?我知道这是一个名为“my_func”的变量,它掩盖了函数my_func
(但定义为my_func
的原始函数仍然存在)。fn
现在似乎引用inner
而不是my_func
,这是通过的。也许它实际上并没有这样做,我误解了一些东西。任何帮助将不胜感激。
我写了以下代码:
def my_func():
print(f"This function's name is '{my_func.__name__}'. Its ID is {hex(id(my_func))}")
return None
def outer(fn):
def inner():
print(f"The function that is about to be called is called '{fn.__name__}'. Its ID is {hex(id(fn))}")
return fn()
return inner
print(f"I have created a function called '{my_func.__name__}'. Its ID is {hex(id(my_func))}")
my_func = outer(my_func)
print(f"The function has been decorated. The variable 'my_func' refers to a function object called '{my_func.__name__}'. Its ID is {hex(id(my_func))}\n")
my_func()
控制台打印如下:
I have created a function called 'my_func'. Its ID is 0x7f3c040cbb50
The function has been decorated. The variable 'my_func' refers to a function object called 'inner'. Its ID is 0x7f3c040f4040
The function that is about to be called is called 'my_func'. Its ID is 0x7f3c040cbb50
This function's name is 'inner'. Its ID is 0x7f3c040f4040
我期待的是:
I have created a function called 'my_func'. Its ID is 0x7f3c040cbb50
The function has been decorated. The variable 'my_func' refers to a function object called 'inner'. Its ID is 0x7f3c040f4040
The function that is about to be called is called 'my_func'. Its ID is 0x7f3c040cbb50
The function that is about to be called is called 'my_func'. Its ID is 0x7f3c040cbb50
我认识到这是
my_func = outer(my_func)
这是“问题”的原因,但我不明白为什么。我曾预计闭包 fn 将继续引用“原始”未修饰的 my_func
函数。我不明白为什么将 my_func
分配给 outer(my_func)
似乎“改变”了 fn 所指的对象。