Python 闭包/修饰函数的变量赋值 -

问题描述 投票:0回答:0

我正在尝试学习 python 中的闭包和装饰器。

我知道,在我下面的代码中,变量 fn 已被分配给一个“单元格”对象,它本身将引用函数对象

my_func
一旦它作为参数传递给函数“外部”并调用外部。

我不明白为什么当从函数

fn
(装饰函数)中调用
inner
时,它调用
inner
(即装饰函数)而不是“原始”未装饰的my_func函数(这是什么作为参数传递给“外部”)

我没想到装饰

my_func
会导致我上面提到的单元格现在引用
my_func
的“不同版本”,它从控制台输出中显示的就是发生的事情。

因此我对下面的代码有两个问题:

  1. 在作业
    my_func = outer(my_func)
    中,作业左侧的“my_func”是什么?我知道这是一个名为“my_func”的变量,它掩盖了函数
    my_func
    (但定义为
    my_func
    的原始函数仍然存在)。
  2. 为什么
    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 所指的对象。

python function variables closures decorator
© www.soinside.com 2019 - 2024. All rights reserved.