Today I Learned

A Hashrocket project

Examining the closure

Python is the first language I’ve encountered that avails you the meta information about the defining closure of a function.

After you get the reference of a function, there is a lot of meta information available via the __code__ attribute. __code__ has many attributes and one of them is co_freevars which is all the variables defined outside of the function, but available through the closure to the function. It returns a tuple. The order of the values in this tuple is important.

The values of those co_freevars are in another dunder (__) method that is called __closure__. It also returns a tuple. The order is the same order as the co_freevars tuple. The tuple holds cell objects with one attribute, cell_contents. cell_contents holds the current co_freevar value.

def get_fn():
    a = 1
    b = 2
    def get():
        print(a)
        print(b)
        return (a, b)
    return get

gfn = get_fn()
gfn.__code__.co_freevars
# ('a', 'b')
gfn.__closure__[0]
# <cell at 0x10849c4f8: int object at 0x1081907c0>
gfn.__closure__[0].cell_contents
# 1
gfn.__closure__[1].cell_contents
# 2