Python 通过值而不是引用定义匿名函数

Python 通过值而不是引用定义匿名函数,python,pass-by-reference,anonymous-function,Python,Pass By Reference,Anonymous Function,在一个循环中,我正在构建一个匿名函数集合。问题是,我想根据我循环的变量的当前值来定义每个函数,但是当这个变量改变时,函数会回顾性地改变,因为值是通过引用传递的 下面是一个简化的示例: c = 8 f = lambda x: x+c f(1) # returns 9 c = 100 f(1) # returns 101 以不变的方式定义函数的惯用方法是什么,这样对其他变量的进一步更改通常不会重新定义函数的行为?(我想这个问题以前也提过,但我找不到关于堆栈溢出的重复问题。)在Python

在一个循环中,我正在构建一个匿名函数集合。问题是,我想根据我循环的变量的当前值来定义每个函数,但是当这个变量改变时,函数会回顾性地改变,因为值是通过引用传递的

下面是一个简化的示例:

c = 8
f = lambda x: x+c

f(1)  # returns 9

c = 100 
f(1)  # returns 101

以不变的方式定义函数的惯用方法是什么,这样对其他变量的进一步更改通常不会重新定义函数的行为?(我想这个问题以前也提过,但我找不到关于堆栈溢出的重复问题。)

在Python中,值永远不会通过引用传递。从未。您将看到使用全局变量的效果。但是,您描述的情况也会发生在自由变量中,例如,在某些函数中,
funcs=[];对于范围(2):funcs.append(lambda:i)
中的i,由于词法范围的限制,解决方案与副本和@Ry中提供的解决方案相同-在下面的注释中,这也是Python中公认的习惯用法,即执行
lambda x,c=c:x+c
。一种更可靠的方法是使用一个单独的函数,该函数接受捕获的值作为参数并返回lambda,例如
def make_f(c):return lambda x:x+c
,它可以内联编写为
(lambda c:lambda x:x+c)(c)
。另外,用另一种方式来说,@juanpa.arrivillaga说,这里确实没有按引用传递(
c
根本没有传递,传递是对参数的处理,Python没有按引用传递)。相反,
c
实际上是lambda内部和外部的同一个变量。(也许你明白了,捕获/结束是一种引用,但不妨指出这一点。)另外,请注意,这不是lambda函数的特殊行为,所有函数在Python中都是这样工作的。@Ry-绝对。这基本上是一个变量范围的问题,而不是评估策略的问题,因为当您声明时,没有传递函数参数。我最讨厌的另一件事是人们把评估策略和任务语义混为一谈。