我在另一个函数中定义了一个函数。
def foo():
x = something
def bar(list=[]):
list.append(x)
return x
return bar
我有两个问题:
- 当我从
foo
返回bar
时,bar
如何保持对x
的访问?此时,x
仅在foo
内部已知,但当我们退出foo
时,bar
如何知道x
是什么 bar
有一个可变的默认参数。当返回的函数bar
超出范围时,这个参数list
是否已从内存中删除?每次我调用bar
时,它都会不断增长,我想确保它在不再使用时被删除
bar
通过创建闭包来保持对x
的访问:
>>> def foo():
... x = 42
... def bar(list=[]):
... list.append(x)
... return x
... return bar
...
>>> func = foo()
>>> func
<function foo.<locals>.bar at 0x7fcae19ac050>
>>> func.__closure__
(<cell at 0x7fcae1b19910: int object at 0x1080d99a0>,)
至于默认的论点,你会问";当返回的函数bar
超出范围时,这个参数list
是否已从内存中删除&";。
函数是对象。对象不会超出范围,范围是变量的属性。如果您的函数对象不再被引用,那么就像任何其他对象一样,它可以用于垃圾收集。在CPython中,这是在引用计数达到零后立即。函数参数的默认值只是作为一个属性存储,就像在任何其他对象中一样:
>>> func.__defaults__
([],)
>>>
所以,是的,所有这些都会像往常一样被清理掉。如果函数对象是唯一引用它的对象,那么当函数对象不存在时,列表的引用计数将达到零,然后它就可以用于垃圾收集。
您可以通过定义一个详细的终结器并将其用作默认值来向自己展示这一点:
>>> class Bar:
... def __del__(self):
... print('goodbye from ', self)
...
>>> def foo():
... def bar(x=Bar()):
... x.baz = 42
... return bar
...
>>> func = foo()
>>> func = foo()
goodbye from <__main__.Bar object at 0x7fcae1b19950>
>>> func = foo()
goodbye from <__main__.Bar object at 0x7fcae1b19910>