Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cell_contents in python closure

Has the cell_contents call for closures in python changed? I understand that func_closure does not work and __closure__ works.

func.__closure__.cell_contents
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'cell_contents'

I am using Python 3.4.1.

like image 808
user1971988 Avatar asked Dec 11 '22 03:12

user1971988


1 Answers

Has the cell_contents call for closures in python changed?

__closure__ is, and always has been, a tuple of cells (even back when it was called func_closure).

Each cell still has a cell_contents member. But the tuple, of course, does not.

So, what you want is probably one of these:

func.__closure__[0].cell_contents

[cell.cell_contents for cell in func.__closure__]

It's worth noting that the details of __closure__ are undocumented and an implementation-specific feature of the CPython implementation. While the data model defines __closure__ as:

None or a tuple of cells that contain bindings for the function’s free variables.

… it doesn't say anything about what those cells are, or that they have an attribute named cell_contents.

But in 3.3+, there's a documented way to get this information, inspect.getclosurevars:

>>> inspect.getclosurevars(func)
ClosureVars(nonlocals={'i': 1}, globals={}, builtins={}, unbound=set())

If you want to know more than what this function returns, you may want to look at how it's implemented in your favorite interpreter (which is probably CPython, given that none of the other major interpreters support 3.3 yet). inspect is one of those modules that's designed to have helpful, readable source, so the docs link directly to the source code. So you can see how it works—but it's basically what you'd expect; if __closure__ isn't None, it just creates a dict mapping each cell name in __code__.co_freevars to the corresponding cell.cell_contents from the tuple.

If you want to go even deeper, I don't know of any good explanations of the internals of closures (that would make a good blog post, and I'll bet someone's written one… but the best I could find in a quick google is Michael Foord's Nothing is Private: Python Closures (and ctypes), but CPython's source for function objects and code objects is pretty readable if you know C and the Python C API. You might also want to consider looking at PyPy, which tends to be a bit more complicated, but it's all in Python. There's also a brief implementation note in PEP 227, which added closures in Python 2.1, but it doesn't explain much.

like image 196
abarnert Avatar answered Jan 20 '23 16:01

abarnert