【问题标题】:Function binding in pythonpython中的函数绑定
【发布时间】:2022-01-16 15:10:37
【问题描述】:
n = 7

def f(x):
    n = 8
    return x + 1

def g(x):
    n = 9
    def h():
        return x + 1
    return h

def f(f, x):
    return f(x + n)

f = f(g, n)
g = (lambda y: y())(f)

我试图了解和跟踪函数绑定中的所有变化,但似乎无法理解为什么 lambda 函数中的 y 参数在被调用时会绑定到 h()。

准确地说,此Python Tutor 链接中从第 14 步到第 15 步的过渡

【问题讨论】:

  • 您知道您的第一个def f(x) 正被def f(f, x): ... 覆盖,对吗?另外,使用与函数名相同的参数名真的很混乱
  • 在任何情况下,f = f(g, n)(同样,命名非常混乱)基本上转换为f = g(14),它将返回def h,关闭x == 14。而(lambda y: y())(f) 只是写f() 的荒谬方式,那么g = h() 就是g = 14 + 1
  • 这就是重点,问题是要我有意跟踪这些绑定中的所有更改,以区分内在函数和它们的名称。问题只是我发布的内容
  • 好的,你看我的第二条评论了吗?同样,请记住,g = (lambda y: y())(f) 只是一种愚蠢的写作方式g = f()
  • Python 从上到下线性执行程序。拿起一支铅笔和一张纸,按照程序进行。请记住将函数名称和函数名称分开。

标签: python python-3.x computer-science higher-order-functions


【解决方案1】:

让我们更改函数的名称,以便更容易理解扭曲的代码。然后我们可以像fun_n 一样按顺序命名,并在每个函数定义后重新分配名称。我也加了一些cmets

第一个是

n = 7

def fun_1(x):
    n = 8
    return x + 1
f = fun1

第二个:

def fun_2(x):
    n = 9
    def h():
        return x + 1
    return h
g = fun_2

现在我们准备好进行一些糟糕的重命名

def fun_3(f, x):
    return f(x + n)
f = fun_3

现在……

f = f(g, n)

相当于fun_3(fun2, n)n=7fun_3 将返回 fun_2(7+n),再次返回 n=7fun_2 将返回带有x=14 的h 闭包,因此它将返回一个返回14 + 1 结果的函数。所以f现在是一个总是返回15的函数

最后,

g = (lambda y: y())(f)

创建一个 lambda 函数,该函数调用传递给它的任何参数,并将 f 作为参数传递给它。相当于:

fun_4 = lambda y: y()
g = fun_4(f)

我不认为它作为练习真的有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多