Speed of Nested Functions & Lambda Expressions

Terry Reedy tjreedy at udel.edu
Wed Oct 24 00:08:32 EDT 2007


"Gary Herron" <gherron at islandtraining.com> wrote in message 
news:471E1BFC.7080101 at islandtraining.com...
| beginner wrote:
| > Hi All,
| >
| > It is really convenient to use nested functions and lambda
| > expressions. What I'd like to know is if Python compiles fn_inner()
| > only once and change the binding of v every time fn_outer() is called
| > or if Python compile and generate a new function object every time. If
| > it is the latter, will there be a huge performance hit? Would someone
| > give some hint about how exactly Python does this internally?

Python the language does not 'do' anything.  The details could be 
implementation specific.

| > def fn_outer(v):
| >     a=v*2
| >     def fn_inner():
| >         print "V:%d,%d" % (v,a)
| >
| >     fn_inner()
| >
| > Thanks,
| > Geoffrey
| >
| >
| The code is compiled only once when the file is initially read in.
| During execution of fn_outer, v will be bound to a value, then a, then
| fn_inner will be bound (to an already compiled code object) and so on.

In CPython, I believe, fn_inner is bound to a *new* *function* object, not 
the once-compiled code object.  It has to be a new object because fn_outer 
could return the inner function, as is not uncommon.  And function objects 
are somewhat mutable.  And each returned function might have different 
values of enclosed outer variables.  However, each function object has the 
same .func_code member.

>>> def outer(n):
 def inner(m):
   return n+m
 return inner

>>> add3 = outer(3)
>>> add3(4)
7
>>> type(add3)
<type 'function'>

| Really, from the point of view of Python while executing fn_outer, the
| def of fn_inner looks just like an assignment with fn_inner as the
| variable name and a code object as the value.

Again, the value is a function object.

Terry Jan Reedy






More information about the Python-list mailing list