[Tutor] python closures

spir denis.spir at free.fr
Tue Dec 1 08:42:47 CET 2009


Dave Angel <davea at ieee.org> dixit:

> Maybe a more complex example might show the various linkages.
> 
> glob = 42
> 
> def outer(parm1):
>     free = 12
>     free3 = 19
>     def inner(parm2, parm3=free3):
>         print "global", glob, ", free vars", parm1, free, free3, ", 
> locals", parm2, parm3
>     free = 49
>     free3 = 48
>     return inner
> 
> newfunc = outer(10)
> newfunc(45)
> 
> 
> produces output:
>    global 42 , free vars 10 49 48 , locals 45 19
> 
> So when the inner() function is actually called, glob is just a global.  
> parm1, fre, and free3 hold the values they ended up with when outer() 
> returned, and local parm2 is passed by top-level code, while local parm3 
> gets its default value assigned when "def inner(...) was executed.
> 
> Notice that the free variables free, free3, and parm1 are referring to 
> the function's ending state, not to the state when the function was 
> defined.  This has an impact when you've got inner being defined in a 
> loop.  And this example could be made more complex if outer() is a 
> generator, in which case it may not have actually ended when inner gets 
> called.
> 
> HTH
> DaveA

Great example, thank you.

By the way, do you know the idiom:

def makeInc(start):
   def inc():
      inc.n += 1
      print inc.n
   inc.n = start
   # 'start' may change now
   # ...
   return inc

inc= makeInc(start=3)
inc()

I find it much nicer than a pseudo default value, for it explicitely shows that 'n' is, conceptually speaking, an attribute of the func (read: a closure upvalue). Let's take advantage of the fact python funcs are real objects!

Denis
________________________________

la vita e estrany

http://spir.wikidot.com/



More information about the Tutor mailing list