[Tutor] python closures

spir denis.spir at free.fr
Mon Nov 30 11:24:45 CET 2009


Below startup definitions:

x = 1

def f():
  n = 1
  def g0(a):
    print (x + n + a) 
  return g0

I'm surprised the snippet below works as expected (py 2.6) without any trick:

g = f()
g(1)	# --> 3

This means a (real) closure is built for g0, or what?
Thought I would need instead to use the old trick of pseudo default-parameters:

def f():
  n = 1
  def g0(a, n=n, x=x):
    print (x + n + a) 
  return g0

to let the inner func g0 "remember" outer values. Why is this idiom used, then? Has something changed, or do I miss a relevant point?

The bit below also works:

x = 2
g(1)	# --> 4

which seems to indicate python really embeds "symbolic references" (*) to outer *variables*, when creating a closure for g0. Not "pointer references" (**), otherwise the replacement of x would not be seen by the closure --like in the case of default-parameter.
Actually, I find this _Bad_. Obviously, the func's behaviour and result depend on arbitrary external values (referentially opaque). What do you think?


(*) by name, indirect access, second table lookup
(**) by address, direct access, no second lookup

la vita e estrany


More information about the Tutor mailing list