3

According to the python tutorial, functions look for variable names in the symbol tables of enclosing functions before looking for global functions:

The execution of a function introduces a new symbol table used for the local variables of the function. More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the local symbol tables of enclosing functions, then in the global symbol table, and finally in the table of built-in names. Thus, global variables cannot be directly assigned a value within a function (unless named in a global statement), although they may be referenced.

What exactly does "enclosing function" mean, and when is it used?

I see the following code prints 10 when called

def parent_function():
    y=10
    def child_function():
        print y
    child_function()

However, calling child_function() alone produces an error. Are enclosing functions used frequently?

dandelion
  • 1,742
  • 1
  • 15
  • 18

3 Answers3

8

The concept of an enclosing function is key in understanding the idea of closures. Because python does not have fully featured lambdas (they only allow expressions and not statements), having nested functions to pass on to other functions is a common use case:

def receiving_function(f):
    f()

def parent_function():
    y = 10

    def child_function():
        print(y)

    receiving_function(child_function)

will print 10 as before. This is a common instance of a closure, where the enclosing function "hands off" it's variables to the enclosed function. In the example above, this function is passed off to the receiving_function along with the non-local variable y.

laike9m
  • 18,344
  • 20
  • 107
  • 140
malloc47
  • 315
  • 1
  • 5
  • Thanks. I'm still a bit confused when this would be useful functionality, which may be because I don't really know what a closure is – dandelion Feb 17 '12 at 22:22
  • 2
    That's a good, though separate question. Consider, for example, if `y=10` was not a simple assignment, but actually a very expensive operation that `child_function` needed. Consider also that, instead of one `child_function`, you had many. Instead of having to put this very expensive computation in each separate function, and have it computed on every function call, you can wrap it in a closure and have it precomputed for this hypothetical set of `child_functions`. Check out [this](http://stackoverflow.com/questions/1305570/closures-why-are-they-so-useful) for a few helpful answers. – malloc47 Feb 18 '12 at 01:03
3

The reason you cannot call child_function by itself, is that it is defined inside the parent_function. All python variable declarations use block scope, and declaring a function is no different.

Consider the following example.

>>> def parent_function():
...    y=10
...    def child_function():
...        print y
...    child_function()

>>> print y
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
NameError: name 'y' is not defined

The variable y is not accessible outside the parent_function. Why would you expect that child_function would be any different that y?

ironchefpython
  • 3,409
  • 1
  • 19
  • 32
  • according to your code it means y , child_function are all local to parent_function() and we don't get any returns from y and child_function outside the parent_function() ? – Praneeth Jun 11 '15 at 14:53
0

Enclosed functions are functions nested in functions. We usually use it to get better encapsulation. That is enclosed functions are not visible outside the eclosing function and they can only be called by the enclosing function.

Community
  • 1
  • 1
Kaoet
  • 367
  • 1
  • 4
  • 14
  • 4
    I think you're confusing "enclosing" with "enclosed": an enclosing function need not be nested in anything, although something must be nested in it (else there is no enclosing going on.) – DSM Feb 17 '12 at 04:28