这个python工厂函数是如何工作的

Geo*_*sen 1 python closures python-3.x

这是我的复数 python 类中的 python 函数:

def raise_to(exp):
    def raise_to_exp(x):
        return pow(x, exp)
    return raise_to_exp
Run Code Online (Sandbox Code Playgroud)

教师现在打开一个交互式会话并执行以下操作:

  • 从 raise_to 导入 raise_to
  • square = raise_to(2),然后继续做
  • 正方形(5)

这会产生 25 的结果。如何或为什么传入两个不同的参数?现在我对这段代码进行了调试,这就是我观察到的。当我这样做时:

def raise_to(exp):
    def raise_to_exp(x):
        return pow(x, exp)
    return raise_to_exp

square = raise_to(2)

print(square)
Run Code Online (Sandbox Code Playgroud)

我明白了 : <function raise_to.<locals>.raise_to_exp at 0x00000246D1A88700>, 但如果我像老师一样去做

def raise_to(exp):
    def raise_to_exp(x):
        return pow(x, exp)
    return raise_to_exp

square = raise_to(2)

print(square(5))

Run Code Online (Sandbox Code Playgroud)

我得到 25。我想知道这是如何工作的。我知道这被称为 python 工厂函数,但它是如何工作的。该函数是否存储第一个参数以供以后使用传入的第二个参数?

che*_*ner 5

raise_to_exp是对由定义的参数的闭包。当你调用 时,你会得到一个函数,在它的函数体中,变量引用了定义范围内的变量。expraise_toraise_to(2)expraise_to_exp

这意味着这square是一个exp绑定到 2的函数,所以大致相当于定义

def square(x):
    return pow(x, 2)
Run Code Online (Sandbox Code Playgroud)

只是为了证明没有更换exp与值2,你可以做一些挖掘到的function对象改变的值exp

>>> square(5)
25
>>> square.__closure__[0].cell_contents = 3  # now square is cube!
>>> square(5)
125
Run Code Online (Sandbox Code Playgroud)