Python 函数生成

Python 函数生成,python,functional-programming,Python,Functional Programming,可能重复: 我没有使用函数组合(f,g),而是执行以下操作 >>> f=g >>> f=lambda x:f(g(x)) >>> f(8) RuntimeError: maximum recursion depth exceeded 我只是想用相应的lambda表达式替换函数组合。我不明白为什么f=composition(f,g)不产生递归,但f=lambda x:f(g(x))产生递归。对于第一个: 当您调用组合(f,g)时,您正在围绕

可能重复:

我没有使用函数组合(f,g),而是执行以下操作

>>> f=g
>>> f=lambda x:f(g(x))
>>> f(8)
RuntimeError: maximum recursion depth exceeded
我只是想用相应的lambda表达式替换函数组合。我不明白为什么f=composition(f,g)不产生递归,但f=lambda x:f(g(x))产生递归。

对于第一个:

当您调用
组合(f,g)
时,您正在围绕这些变量的内容创建一个闭包。返回的lambda在其局部范围内查找变量名
f
g
——它们都是对第一行创建的
g
lambda的引用

关于第二个问题:

在第二个函数中,当调用
f
时,它在其“局部”作用域(实际上是全局作用域)中查找
f
,并找到自己,从而创建无限递归

这里的关键是
f
的查找是在执行时进行的,而不是在定义lambda时。

编写此代码时:

f=lambda x:f(g(x))
f=composition(f, g)
结果lambda表示“调用x上作用域中的任何g的结果,调用作用域中的任何f”

当你写这篇文章时:

f=lambda x:f(g(x))
f=composition(f, g)
结果函数的意思是“调用composition的第一个参数的结果,调用composition的第二个参数的结果”

我不确定你需要更好地理解哪一部分细节来解决这个问题,但我猜一下。Python中传递的参数总是通过引用,而不是通过名称。因此,当您调用组合(f,g)时,您传递的是f引用的函数对象,而不是“变量”f。但是当你定义一个lambda时,它只发生在作用域中,所以你引用的是f本身

另外,这也是Guido不喜欢使用lambda语法的人的部分原因。如果您像这样重写代码,那么发生的事情会更加明显:

def g(x): return x+1
def composition(f,g):
  def composed(x): return f(g(x))
  return composed
f=g
f=composition(f,g)