[Tutor] learning nested functions
eryksun
eryksun at gmail.com
Wed Jul 10 22:54:53 CEST 2013
On Mon, Jul 8, 2013 at 2:26 AM, Tim Hanson <tjhanson at yahoo.com> wrote:
>
> No problem so far. I made a change and ran it again:
>
>>>> def f1():
> x=88
> def f2():
> print(x)
> x=99
> print(x)
> f2()
You need to use a "nonlocal" declaration (3.x only). Using nonlocal
explicitly creates a closure. In your first example this was done
implicitly. But since you're assigning to x, the compiler assumes you
want a local unless you tell it otherwise.
def f1():
x = 88
def f2():
nonlocal x
print(x)
x = 99
print(x)
return f2
>>> f2 = f1()
>>> f2()
88
99
To pull this off Python creates a cell object that's shared by both
frames. The cell lives as long as it's referenced:
>>> f2.__closure__[0].cell_contents
99
>>> sys.getrefcount(f2.__closure__[0]) - 1
1
I subtracted 1 for the getrefcount call. The reference is only 1
because the frame for f1 is already garbage collected. If you call f1
again, it creates a new cell for 'x' and a new f2. As you can imagine
the bytecode for working with cells is different, and this affects f1
and f2 equally. Instead of LOAD_FAST and STORE_FAST, they use
LOAD_DEREF and STORE_DEREF.
More information about the Tutor
mailing list