Is there a way to change the closure of a python function?
Terry Reedy
tjreedy at udel.edu
Tue Sep 27 17:19:02 EDT 2016
On 9/27/2016 11:01 AM, Chris Angelico wrote:
> On Wed, Sep 28, 2016 at 12:01 AM, Peng Yu <pengyu.ut at gmail.com> wrote:
>> Hi, In many other functional language, one can change the closure of a
>> function. Is it possible in python?
>>
>> http://ynniv.com/blog/2007/08/closures-in-python.html
>>
>
> From the blog post:
>
> """In some languages, the variable bindings contained in a closure
> behave just like any other variables. Alas, in python they are
> read-only."""
>
> This is not true, at least as of Python 3.
>
> def makeInc(x):
> def inc(y, moreinc=0):
> # x is "closed" in the definition of inc
> nonlocal x
> x += moreinc
> return y + x
> return inc
The value of the cell variable is writable from within the body of the
closure function if declared nonlocal, but not otherwise, and not from
without. The latter may be what Peng meant by 'change' and the blogger
by 'read-only'.
def makeInc(x):
def inc(y, moreinc=0):
# x is "closed" in the definition of inc
nonlocal x
x += moreinc
return y + x
return inc
f = makeInc(23)
fclose = f.__closure__ # a tuple of 'cells'
fcell = fclose[0]
print(dir(fcell))
# ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__',
# '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__',
# '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__',
# '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
# '__sizeof__', '__str__', '__subclasshook__', 'cell_contents']
# Note: no mutation method
print('cell content = ', fcell.cell_contents)
# cell content = 23
fcell.cell_contents = 32
### results in
Traceback (most recent call last):
File "F:\Python\mypy\tem.py", line 14, in <module>
fcell.cell_contents = 32
AttributeError: attribute 'cell_contents' of 'cell' objects is not writable
# unless one does so from within the closure body with 'nonlocal'
declaration. I presume there is a special byte code for this.
--
Terry Jan Reedy
More information about the Python-list
mailing list