Skip to main content
 首页 » 编程设计

python之python中变量/函数捕获背后的机制是什么

2025年05月04日8lyhabc

这个问题在这里已经有了答案:





Creating functions in a loop

(4 个回答)


3年前关闭。




我正在尝试生成许多函数 f取决于变量并将它们存储到列表中fs .

我第一次尝试

fs = [] 
for v in range(3): 
  def f(): 
    print(v) 
  fs.append(f) 
 
for f in fs: 
  f() 

但这输出
2 
2 
2 

即只调用最后一个函数。

我认为这可能是因为函数 f在每个循环中被覆盖,但后来我尝试了
fs = [] 
for v in range(3): 
  def f(): 
    print(v) 
  fs.append(f) 
  def f(): 
    print('foo') 
  fs.append(f) 
 
for f in fs: 
  f() 

哪个输出
2 
foo 
2 
foo 
2 
foo 

所以看起来python至少能够区分这两个同名的函数。

然后我虽然我会动态创建 f :
fs = [] 
for v in range(3): 
  def make_f(): 
    def f(): 
      print(v) 
    return f 
  fs.append(make_f()) 
 
for f in fs: 
  f() 

但这仍然输出
2 
2 
2 

最后,我参数化了 make_v工厂,终于得到了我想要的结果:
fs = [] 
for v in range(3): 
  def make_f(v): 
    def f(): 
      print(v) 
    return f 
  fs.append(make_f(v)) 
 
for f in fs: 
  f() 

打印
0 
1 
2 

尽管我最终破解了一个解决方案,但我认为我对 python 如何在这些情况下捕获变量或函数确实缺乏一些更深入的了解。有人可以解释这种行为背后的理由吗?有没有更直接的方法来实现我最初想做的事情?

请您参考如下方法:

问题在于变量绑定(bind),因为它们引用了 v在最终为 2 的全局范围内。您可以通过将变量绑定(bind)到本地范围来解决此问题。

fs = [] 
for v in range(3): 
  def make_f(v=v): 
    def f(): 
      print(v) 
    return f 
  fs.append(make_f()) 
 
for f in fs: 
  f() 

希望这有助于您进一步了解正在发生的事情。