In code that’s compiled to use optimized (i.e. fast) locals, dynamic locals and import *
are not supported, and if a variable is local, then it’s always local. Note that in this case, trying to reference a local variable before it’s assigned, or after it’s deleted, will raise UnboundLocalError
. With this knowledge in hand, the compiler knows that a free variable that’s not from an enclosing function scope can be assumed to be in globals or builtins. It thus uses the opcode LOAD_GLOBAL
, which checks f_globals
and f_builtins
.
The above is in contrast to code that’s compiled to use non-optimized locals (i.e. locals stored in the f_locals
mapping), such as the top-level code of a class body, module, or exec()
. In this case, the scope of a name can change fluidly between locals and globals, or locals and nonlocals. Also, dynamic locals are supported, as well as import *
usually (except not in a class body). Unless a variable is explicitly declared global, or is from an enclosing function scope, the compiler references it via LOAD_NAME
, which checks f_locals
, f_globals
, and f_builtins
, in that order. If a variable is explicitly declared global, then LOAD_GLOBAL
is used instead of LOAD_NAME
.
In a class body, a variable from an enclosing function scope may be referenced by the opcode LOAD_CLASSDEREF
, which is a hybrid lookup. If the name isn’t defined in the f_locals
mapping, the interpreter falls back on loading the cell object from the enclosing scope and dereferencing its contents. Note that if the name is assigned to as a local variable, then the compiler will reference the variable using LOAD_NAME
instead of LOAD_CLASSDEREF
, except if the assigned variable is declared nonlocal. For example:
def f():
x = 'nonlocal 1'
class C:
nonlocal x
print(x)
x = 'nonlocal 2'
print(x)
x = 'nonlocal 3'
locals()['x'] = 'local' # dynamic assign
print(x)
del locals()['x'] # dynamic delete
print(x)
>>> f()
nonlocal 1
nonlocal 2
local
nonlocal 3