[Edu-sig] Function Question -- I'm confused...

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Mon, 17 Sep 2001 13:37:21 -0700 (PDT)


On Mon, 17 Sep 2001 WHITSTON@ltu.edu wrote:

> Over the weekend I was reading a Python textbook and in the chapter on
> functions it mentioned that Python functions could have embedded
> functions like Pascal.  Since other textbooks don't mention this
> "feature", I'm wondering whether it is true or not (or was/is part of
> a particular version).


Yes, it's possible to nest functions in functions:

>>> def function1():
...     def function2():
...         print "Hey, ho, the wind and the rain"
...     function2()
...     function2()
... 
>>> function1()
Hey, ho, the wind and the rain
Hey, ho, the wind and the rain
>>> function2()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: name 'function2' is not defined
###

Note that, outside of function1(), the global environment doesn't know
what function2() looks like.  We can think of function2() as if it were a
local variable.


Here's a somewhat more complicated, but powerful, example of using
functions within functions:

###
from __future__ import nested_scopes
from operator import isSequenceType

def deepen(f):
    """Given a function 'f' that takes a single argument,
    returns a new function that can deeply apply 'f'
    across sequences."""
    def deep_function(thing):
        if isSequenceType(thing):
            return map(deep_function, thing)
        return f(thing)
    return deep_function
###


And here it is in action:
###
>>> def square(x): return x * x
>>> deep_squarer = deepen(square)   ## We create a "deep" version of
                                    ## square().

>>> deep_squarer(5)                 ## It still knows how to deal with
                                    ## single elements...
25

>>> deep_squarer( [5, 6, [7, 8], [[9]]] )  ## But things get interesting
[25, 36, [49, 64], [[81]]]                 ## when we give it larger
                                           ## structures!


In most cases, I don't nest functions because it makes it impossible to
call them from outside of the enclosing function.  This makes it difficult
to directly test them.  However, nested functions become more interesting
when we have lexical ("nested") scoping.


If you have more questions, please feel free to ask!