Monday, November 19, 2012
There have been discussions about back-porting the nonlocal keyword from Python 3 to Python 2.
But, is there some crazy, misguided hack we can use to edit closures in Python 2?
Let's make a closure!
>>> def foo():
... a = 2
... def bar():
... print a
... return bar
(<cell at 0x02515FF0: int object at 0x023AA6CC>,)
A closure apparently consists of a tuple of cell objects. The tuple is immutable. What about the cell itself?
>>> foo().func_closure.cell_contents = 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: attribute 'cell_contents' of 'cell' objects is not writable
Well played, Python 2.7 runtime. Time to go nuclear: the python C api.
>>> b = foo()
>>> import ctypes
>>> ctypes.pythonapi.PyCell_Set(id(b.func_closure), id(3))
So, there you have it. The contents of a closure can be changed in Python 2.