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:
a=6
and b=7
are initialized.outer_func
is called:outer_func
defines a local variable, len=2
.a
and b
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.len
(2) is printed.inner_func
is called:a=9
is defined.b
is printed; b
doesn't exist in local scope so Python looks for it in enclosing scope, that of outer_func
. It isn't found there either, so Python proceeds to look in global scope where it is found: the value b=7
is printed.len
is printed: len
doesn't exist in local scope, but it is in the enclosing scope since len=2
is defined in outer_func
: its value is outputouter_func
has finished execution, the values of a
and b
in global scope are printed.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
).