Отмена оператора «global <var>» - PullRequest
2 голосов
/ 13 октября 2010

Я изучаю Python и только что задал этот вопрос.Возможно, это не имеет практической ценности, я спрашиваю об этом, может быть, из-за педантичного любопытства.

У меня есть функция:

def f():
    x = 12    #this is a local variable
    global x  #this is a global I declared before
    x = 14    #changes global x

    <How can I return the local x?>

Я знаю, что это уродливо, и яполучить предупреждение о синтаксисе.Просто хотел узнать, как «вернуть» мою локальную переменную.

Спасибо всем.

Ответы [ 3 ]

7 голосов
/ 13 октября 2010

Ваш код не делает то, что вы думаете, и нет никакого способа изменить его, сделайте то, что вы описываете. Вы не можете «вернуть» то, что делает globals, так как это не имеет никакого эффекта во время выполнения.

Ключевое слово global интерпретируется в время компиляции , поэтому в первой строке f(), где вы устанавливаете x = 12, это модифицирует глобальный x, так как компилятор определил x относится к x в глобальном пространстве имен во всей функции, а не только после оператора global.

Вы можете легко проверить это:

>>> def g():
...     x = 12
...     y = 13
...     global x
...     print "locals:",locals()
...
<stdin>:4: SyntaxWarning: name 'x' is assigned to before global declaration
>>> g()
locals: {'y': 13}

Функция locals() дает нам представление о локальном пространстве имен, и мы видим, что там нет x.

В документации говорится следующее :

Имена, перечисленные в операторе global, не должны использоваться в том же кодовом блоке, текстуально предшествующем инструкции global.

Имена, перечисленные в операторе global, не должны определяться как формальные параметры или в for целевом элементе управления циклом, class определении, определении функции или import операторе.

Текущая реализация не применяет последние два ограничения, но программы не должны злоупотреблять этой свободой, так как будущие реализации могут применять их или молча менять значение программы.

Просто дайте локальной переменной другое имя.

4 голосов
/ 13 октября 2010

Я очень сомневаюсь, что это можно сделать.

>>> x = 1
>>> def f():
...     x = 12
...     global x
...     print x
... 
<stdin>:3: SyntaxWarning: name 'x' is assigned to before global declaration
>>> f()
12
>>> x
12

Как видите, даже без явного присвоения x после ключевого слова global python синхронизирует значениядва.Чтобы понять почему, вам нужно разобрать его.

>>> dis.dis(f) # different f with print statement removed for clarity
  2           0 LOAD_CONST               1 (12)
              3 STORE_GLOBAL             0 (x)

  3           6 LOAD_CONST               0 (None)
              9 RETURN_VALUE        
>>> 

Ключевое слово global здесь вообще не представлено, но оператор присваивания компилируется как STORE_GLOBAL.После того, как вы это сделаете, это сделано.Используйте глобальные слова с осторожностью и ключевое слово global с большей осторожностью.

1 голос
/ 13 октября 2010

Невозможно отменить действие оператора global.

A global оператор применяется ко всей продолжительности функции, в которой он появляется, независимо от того, где в функции он находитсяи независимо от того, выполнено ли оно.Так, например, в присваивании в следующей функции:

def f():
    x = 3
    if False:
        global x

x по-прежнему обрабатывается как глобальное.

Так что не имеет смысла иметь другой оператор для отменыего эффект впоследствии, поскольку global «оператор» - это не столько оператор, который выполняется в какой-то момент во время функции, сколько объявление поведения функции в целом.

...