Это довольно просто, согласно Python FAQ (с моим акцентом):
В Python, переменные, на которые есть только ссылка внутри функции неявно глобальные. Если переменной присвоено значение в любом месте тела функции, оно считается локальным, если явно не объявлено как глобальное.
Итак, если вы присвоите переменной где-нибудь внутри функции, эти переменные считаются локальными везде в функции, что приводит к таким проблемам, как:
def fn():
print(s) # Use before assignment, despite one s being
global s # set before calling.
s = 42
s = 7
fn()
Это означает, что если вы хотите измените глобальный, вам нужно пометить как глобальный внутри функции.
Если единственное, что вы делаете, это , используя глобальный, это не требуется, но я все равно отмечаю его, на случай, если позже захочу изменить его, и для ясности намерений (я использую глобальные переменные достаточно редко, чтобы это почти никогда не возникало).
Причина, по которой ваш код семпл не работает:
def f():
global s
s = "Only in spring, but London is great as well!"
print(s)
print(s)
f()
потому что s
не существует в точке, где вы его сначала печатаете (до вызова функции). Даже если global
создаст переменную, этого не произойдет, пока функция не будет вызвана, после этого первого print
.
В любом случае, global
делает не создает переменную, она просто указывает функции использовать глобальную переменную при присваивании. Это видно из следующего кода:
def f():
global s
print(s)
f()
, который также жалуется на несуществование s
.
С точки зрения создания глобалов, они появляются, когда вы назначаете им. Вы можете назначить им вне функцию:
def fn():
print(s) # global because function doesn't assign to it.
# Unassigned here
s = 42
# Assigned here
fn()
или вы можете назначить им внутри функцию , если они отмечены global.
def fn():
global s
# Unassigned here
s = 42
# Assigned here
print(s) # global because you said so.
# Unassigned here
fn()
# Assigned here
В отсутствие этих случаев существует only local:
def fn():
# Global unassigned here ...
s = 42
# ... and here
print(s) # local.
# Global unassigned here
fn()
# ... and here.