Нет. Все как раз очень очевидно.
Модули (а также классы и функции) - компилируются в байткод перед исполнением. Определение не совсем строгое - но сойдет.
>>> import dis
>>> b = "Hello"
>>> def a():
... print b
...
>>> dis.dis(a)
2 0 LOAD_GLOBAL 0 (b)
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
Т.е. b в данном случае - глобальное имя, потому что не было присваивания (инициализации) внутри функции a.
То же самое с явным заданием global
>>> def a():
... global b
... print b
...
>>> dis.dis(a)
3 0 LOAD_GLOBAL 0 (b)
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
А теперь - с инициализацией
>>> def a():
... print b
... b = 'world'
...
>>> dis.dis(a)
2 0 LOAD_FAST 0 (b)
3 PRINT_ITEM
4 PRINT_NEWLINE
3 5 LOAD_CONST 1 ('world')
8 STORE_FAST 0 (b)
11 LOAD_CONST 0 (None)
14 RETURN_VALUE
LOAD_FAST/STORE_FAST - опкоды для доступа к локальной переменной. Которой в начале еще нет.
С вложенными функциями - отдельная тема. Говоря коротко, питон смотрит в вызываемушую функцию перед тем, как смотреть в global scope. Если имя есть - оно помещается в func_closure и используется.
>>> def f():
... v = 'Hello'
... def g():
... print v
...
>>> dis.dis(f)
2 0 LOAD_CONST 1 ('Hello')
3 STORE_DEREF 0 (v)
3 6 LOAD_CLOSURE 0 (v)
9 BUILD_TUPLE 1
12 LOAD_CONST 2 (<code object g at 025802F0, file "<interactive input>", line 3>)
15 MAKE_CLOSURE 0
18 STORE_FAST 0 (g)
21 LOAD_CONST 0 (None)
24 RETURN_VALUE
>>>
Обратите внимание на LOAD_CLOSURE
В “классическом” Python 2.x нет способа переопределить имя для closure. Т.е. в g() нельзя написать v=3. Это будет распознано как создание локальной переменной. Стандартный способ обхода - использовать списки v = , затем v = ‘world’
В Python 3.x появилось новое слово nonlocal для этих целей.
>>> def f():
v = "Hello"
def g():
nonlocal v
print (v)
v = "world"
print (v)
return g
>>> dis.dis(f)
2 0 LOAD_CONST 1 ('Hello')
3 STORE_DEREF 0 (v)
3 6 LOAD_CLOSURE 0 (v)
9 BUILD_TUPLE 1
12 LOAD_CONST 2 (<code object g at 0x027BC698, file "<pyshell#14>", line 3>)
15 MAKE_CLOSURE 0
18 STORE_FAST 0 (g)
8 21 LOAD_FAST 0 (g)
24 RETURN_VALUE
>>> dis.dis(f())
5 0 LOAD_GLOBAL 0 (print)
3 LOAD_DEREF 0 (v)
6 CALL_FUNCTION 1
9 POP_TOP
6 10 LOAD_CONST 1 ('world')
13 STORE_DEREF 0 (v)
7 16 LOAD_GLOBAL 0 (print)
19 LOAD_DEREF 0 (v)
22 CALL_FUNCTION 1
25 POP_TOP
26 LOAD_CONST 0 (None)
29 RETURN_VALUE
Тема не совсем тривиальная - так что спрашивайте.