Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python __closure__ variables and cells

While exploring some solutions to my previous question about the inner workings of Python scope, I learned about the __closure__ attribute. It seems that Python uses this attribute to access variables defined in an outer scope from within a nested function.

We can see this in action by doing the following:

def foo():
    x = 5
    def bar(): 
        print(x)
        print(*(cell.cell_contents for cell in bar.__closure__))
    bar()
foo()

This shows two enclosed values, 5 and the function bar itself.

What I don't understand is how this works - since, the __closure__ attribute merely contains a tuple of cells which store the enclosed values. But there's no information about the enclosed variables names - (i.e. the cells are stored in a tuple, not a dict). So how does Python know the names of the variables which have been enclosed?

like image 295
Channel72 Avatar asked Feb 20 '23 06:02

Channel72


1 Answers

The python compiled code uses indices; the variables are tied to an index into the cells structure.

>>> def foo():
...     x = 5
...     def bar():
...         return x
...     return bar
... 
>>> bar = foo()
>>> import dis
>>> dis.dis(bar)
  4           0 LOAD_DEREF               0 (x) 
              3 RETURN_VALUE         

The LOAD_DEREF bytecode refences the first cell value.

like image 93
Martijn Pieters Avatar answered Feb 22 '23 05:02

Martijn Pieters