Python在哪里存储函数闭包的名称绑定? [英] Where does Python store the name binding of function closure?

查看:87
本文介绍了Python在哪里存储函数闭包的名称绑定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以最近我了解了函数闭包的概念。

So recently I understand the concept of function closure.

def outer():
    somevar = []
    assert "somevar" in locals() and not "somevar" in globals()
    def inner():
        assert "somevar" in locals() and not "somevar" in globals()
        somevar.append(5)
        return somevar
    return inner

function = outer()
somevar_returned = function()
assert id(somevar_returned) == id(function.func_closure[0].cell_contents)

可以理解,函数关闭的目的是保持对对象的主动引用,以避免对该对象进行垃圾回收。这就是为什么以下方法可以正常工作的原因:

As much as I understand, the objective of function closure is to keep an active reference to the object, in order to avoid garbage collection of this object. This is why the following works fine :

del outer
somevar_returned_2 = function()
assert id(somevar_returned) == id(function.func_closure[0].cell_contents)
assert id(somevar_returned) == id(somevar_returned_2)

事情是(据我所知)在执行 inner 函数之前,Python会重建本地变量字典。该词典将包含:

The thing is (always as much as I understood) before the execution of the inner function, Python rebuild the locals variables dictionary. This dictionary will contains :


  • 与函数的单元格内容关联的闭包名称

  • 函数的参数与它们的默认值或给定参数相关联的名称(并且它可以覆盖先前的名称)

问题是Python在哪里存储名称绑定的关闭?我在任何地方都找不到它。

The question is where do Python store the name binding of the closure ? I can't find it anywhere.

注意:函数的属性:

>>> print "\n".join("%-16s : %s" % (e, getattr(function, e)) for e in dir(function) if not e.startswith("_") and e != "func_globals")
func_closure     : (<cell at 0x2b919f6bc050: list object at [...]>,)
func_code        : <code object inner at [...], file "<stdin>", line 4>
func_defaults    : None
func_dict        : {}
func_doc         : None
func_name        : inner


推荐答案

这取决于python实现。我假设您的意思是CPython。

__ code __ (或 func_code )具有 co_freevars 属性,该属性包含所有非局部变量的名称(它们被称为免费vars,就好像python函数是逻辑上的

The __code__ (or func_code) has a co_freevars attribute that contains the name of all non-local variables (they are called "free vars" as if a python function was a logical formula where the arguments and local variables are quantified variables)

从这些各种属性中,您可以获取从本地和非本地名称到单元格的映射。

From these various attribute you can obtain a mapping from local and non-local names to cells.

In [35]: function.__code__.co_freevars
Out[35]: ('somevar',)

co_varnames 属性列出了所有本地定义的名称:

The co_varnames attribute lists all locally define names:

In [36]: function.__code__.co_varnames
Out[36]: ()
In [37]: def outer():
    ...:     somevar = ["stackoverflow"]
    ...:     def inner():
    ...:         x = 1
    ...:         somevar.append(5)
    ...:         return somevar
    ...:     return inner
    ...: 
    ...: function = outer()

In [38]: function.__code__.co_varnames
Out[38]: ('x',)

co_cellvars 表示 inner 函数使用哪些本地名称:

While co_cellvars says which local names are used by inner functions:

In [43]: outer.__code__.co_cellvars
Out[43]: ('somevar',)

所有闭包函数均具有 __ closure __ 属性。此属性返回单元格对象的元组。并且单元格对象具有 cell_contents 属性,该属性存储变量的值。

All closure functions have __closure__ attribute. This attribute returns a tuple of cell objects. And The cell object has cell_contents attribute which stores the value of variable.

In [44]: function.__closure__
Out[44]: (<cell at 0x7f4e06b002b8: list object at 0x7f4e06b522c8>,)
In [45]: function.__closure__[0].cell_contents
Out[45]: ["stackoverflow"]

这篇关于Python在哪里存储函数闭包的名称绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆