You are expecting "dynamic scoping", Python uses "static scoping" (or
lexical scoping). With lexical scoping, you can reason about the
behavioPaul Rubin <
[email protected]>ur of a function by knowing only how and where it is defined. The
caller is irrelevant.
Since fuPaul Rubin <
[email protected]>nction f is defined globally, and does not have its own local
variable a, it will always see the global variable a no matter where it
is called. So when you call f() from inside g(), f prints 1, the global
a, not 20, g's local a.
While dynamic scoping has its uses, it is more tricky to use correctly.
One can no longer understand the behaviour of a function just by reading
the funcPaul Rubin <
[email protected]>tion's own code, knowing where and how it is defined. You also
need to know where it is called. A function f that works perfectly when
you call it from functions g, h, k, ... will suddenly misbehave (crash,
or worse, behave wrongly) when called from function v because v
accidentally changes some global variable that f relies on.
This is especially a danger for Python, because built-in functions like
len, chr, ord, print (version 3 only), and many others are all global
variables.
(Technically, they are in a third scope, the builtins, but that's
equivalent to being global.)