The locals for a function consist of everything that was passed in, and every variable that is assigned to and not explicitly tagged as global
(or nonlocal
in 3.x).
The globals consist of everything that can be seen at global scope, including the function itself.
When a name is referenced, it is looked up in the locals first, and then in the globals if not found in the locals.
When the statement f(g)
is run, the statement itself is at global scope, so there are no locals. f
and g
are both found in the globals: they are both functions. The function defined by def f...
is called, with the function defined by def g...
being passed as an argument.
When f(f)
runs, f
is in the locals for the function. It is bound to the passed-in value, which is the function defined by def g...
. The body of the function has the statement f(1)
. 1
is a constant and no lookup is required. f
is looked up in the locals, and the passed-in function is found. It - being the function known at global scope as g
- is called.
Thus g
is, likewise, run with the value 1
bound to the local variable x
. That is forwarded to the function print
(in 3.x; in 2.x, print
is a keyword, so print x
is a statement), which prints the value 1
.