Поиск более глубокого понимания глобального ключевого слова внутри функций в Python 3 - PullRequest
1 голос
/ 24 апреля 2020

Первый пост на Overstack.

Я новичок в Python и кодировании в целом. Сейчас я изучаю функции и в настоящее время смотрю на некоторые примеры, описывающие глобальные переменные в Python -Course.eu :

def f():
    global s
    print(s)
    s = "Only in spring, but London is great as well!"
    print(s)
s = "I am looking for a course in Paris!" 
f()
print(s)

, которые дают вывод:

I am looking for a course in Paris!
Only in spring, but London is great as well!
Only in spring, but London is great as well!

Итак, насколько я понимаю, ключевое слово global меняет значение глобальной переменной s на "Только весной, но Лондон тоже великолепен!"? Это точно?

Если это так, если я присваиваю global переменной внутри функции и не присваиваю значение s вне функции Я получаю ошибку? Означает ли это, что ключевое слово global может изменять только назначенную глобальную переменную?

Например, почему я не могу сделать это:

def f():
  global s
  s = "Only in spring, but London is great as well!"
  print(s)
print(s)
f()

I заметил, что если я сначала запустил функцию, она работает. Значит ли это, что мне нужно запустить функцию, чтобы назначить глобальную переменную?

Этот вопрос не столько о попытке заставить работать кусок кода, сколько о том, как понять, как Python работает и почему. Спасибо, и я прошу прощения, если на этот вопрос уже был дан ответ. Я просто не смог найти ответ. Большое спасибо заранее.

Ответы [ 3 ]

1 голос
/ 24 апреля 2020

Это довольно просто, согласно 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.
0 голосов
/ 24 апреля 2020

Что вам не хватает, так это порядок выполнения операторов здесь. Как вы заметили, если вы сначала запустите функцию, она будет работать:

# 1 definition of function f - don't parse or run the code inside here, just know it exists.
def f():
  # 4 ... global statement
  global s
  # 5 assign a value to `s` (the global)
  s = "Only in spring, but London is great as well!"
  # 6 run print function with parameter `s`
  print(s)
# 2 run print function with variable `s` as input. `s` doesn't exist. error.
print(s)
# if we pretend we skip the print
# 3 run the function `f`
f()
# After running `f()` `s` is now defined in the global scope

Что вам может пригодиться для проверки этого, так это проверка содержимого locals() и globals(), которые являются встроенными функциями, которые возвращают словарь всего, что находится в области видимости, так что вы можете видеть, как оно меняется на основе назначений и определений функций.

0 голосов
/ 24 апреля 2020

В первом примере вам нужно взглянуть на последовательность вашего кода. По сути, код будет в таком порядке в зависимости от вашей последовательности.

s = "I am looking for a course in Paris!" 
print(s)
s = "Only in spring, but London is great as well!"
print(s)
print(s)

Второй пример, почему это не удалось, поскольку вы не объявили переменную s. global просто объявляет область видимости переменной s, но вы должны определить ее.

С уважением, Paul

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...