Learning Scientific Programming with Python (2nd edition)
E2.28: Function Scope
Take a moment to study the below code and predict the result before running it.
def outer_func():
def inner_func():
a = 9
print('inside inner_func, a is {:d} (id={:d})'.format(a, id(a)))
print('inside inner_func, b is {:d} (id={:d})'.format(b, id(b)))
print('inside inner_func, len is {:d} (id={:d})'.format(len,id(len)))
len = 2
print('inside outer_func, a is {:d} (id={:d})'.format(a, id(a)))
print('inside outer_func, b is {:d} (id={:d})'.format(b, id(b)))
print('inside outer_func, len is {:d} (id={:d})'.format(len,id(len)))
inner_func()
a, b = 6, 7
outer_func()
print('in global scope, a is {:d} (id={:d})'.format(a, id(a)))
print('in global scope, b is {:d} (id={:d})'.format(b, id(b)))
print('in global scope, len is', len, '(id={:d})'.format(id(len)))
This program defines a function, inner_func
nested inside another, outer_func
. After these definitions, the execution proceeds as follows:
- Global variables
a=6
andb=7
are initialized. outer_func
is called:outer_func
defines a local variable,len=2
.- The values of
a
andb
are printed; they don't exist in local scope and there isn't any enclosing scope, so Python searches for and finds them in global scope: their values (6 and 7) are output. - The value of local variable
len
(2) is printed. inner_func
is called:- A local variable,
a=9
is defined. - The value of this local variable is printed.
- The value of
b
is printed;b
doesn't exist in local scope so Python looks for it in enclosing scope, that ofouter_func
. It isn't found there either, so Python proceeds to look in global scope where it is found: the valueb=7
is printed. - The value of
len
is printed:len
doesn't exist in local scope, but it is in the enclosing scope sincelen=2
is defined inouter_func
: its value is output
- A local variable,
- After
outer_func
has finished execution, the values ofa
andb
in global scope are printed. - The value of
len
is printed. This is not defined in global scope, so Python searches its own built-in names:len
is the built-in function for determining the lengths of sequences. This function is itself an object and it provides a short string description of itself when printed.
Here is the output:
inside outer_func, a is 6 (id=232)
inside outer_func, b is 7 (id=264)
inside outer_func, len is 2 (id=104)
inside inner_func, a is 9 (id=328)
inside inner_func, b is 7 (id=264)
inside inner_func, len is 2 (id=104)
in global scope, a is 6 (id=232)
in global scope, b is 7 (id=264)
in global scope, len is <built-in function len> (id=977)
Note that in this example outer_func
has (perhaps unwisely) redefined ("re-bound") the name len
to the integer object 2
. This means that the original len
built-in function is not available within this function (and neither is it avaiable within the enclosed function, inner_func
).