Where does Python store the name binding of function closure?

前端 未结 2 973
长发绾君心
长发绾君心 2020-12-16 04:35

So recently I understand the concept of function closure.

def outer():
    somevar = []
    assert \"somevar\" in locals() and not \"somevar\" in globals()
          


        
2条回答
  •  臣服心动
    2020-12-16 04:53

    This depends on the python implementation. I assume you mean CPython.

    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',)
    

    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',)
    

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

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

    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]: (,)
    In [45]: function.__closure__[0].cell_contents
    Out[45]: ["stackoverflow"]
    

提交回复
热议问题