调用返回的函数对象并不显示相同的结果? Python3.x

时间:2017-07-06 00:09:43

标签: python python-3.x

为什么拨打f()()的电话与h=f()h()的电话不同 当f()h的ID相同时?

Python程序:

def f():
  c = [0]
  def g():
    c[0] += 1
    return c[0]
  return g

print (id(f()), id(f()))
print (f()(), f()())

h = f()
print (id(h))
print (h(), h())

输出:

140383530386568 140383530386568
1 1
140383530386568
1 2

修改
为什么c的值仍然存在?

2 个答案:

答案 0 :(得分:3)

为了回答你的第二个问题,内部函数记住c的值的原因是由于python中一个名为 function closures 的概念。

>>> def print_msg(msg):
...     def foo():
...         print(msg)
...     return foo
... 
>>> f = print_msg('hello')
>>> f()
hello

即使变量超出范围或从当前命名空间中删除了函数本身,也会记住封闭范围中的此值。

您可以通过访问__closure__挂钩f._closure__[0].cell_contents来查看函数闭包的内容。

要回答您的第一个问题,当您拨打f()()两次时,您可以动态创建并返回功能。因此,每次使用新版本c重新创建函数时。第二次,当您将其分配给变量h时,您保留对内部函数的引用,因此保留c的值,因为我之前提到过。因此,第二次调用相同的函数时,c[0]的值会递增。

答案 1 :(得分:2)

python中有一个概念closure

当您致电f时,返回的对象包含__closure__属性。 您可以致电h.__closure__进行检查,在您的情况下,您可以获得 c致电h.__closure__[0].cell_contents

  

闭包是一种函数,它保留定义函数时存在的自由变量的绑定,以便稍后在调用函数并且定义范围不再可用时可以使用它们。 - 流利的Python