Вопрос-Ответ

Why isn't the 'global' keyword needed to access a global variable?

Почему ключевое слово 'global' не требуется для доступа к глобальной переменной?

Насколько я понимаю, в Python есть отдельное пространство имен для функций, поэтому, если я хочу использовать глобальную переменную в функции, мне, вероятно, следует использовать global.

Однако я смог получить доступ к глобальной переменной даже без global:

>>> sub = ['0', '0', '0', '0']
>>> def getJoin():
... return '.'.join(sub)
...
>>> getJoin()
'0.0.0.0'

Почему это работает?


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

Переведено автоматически
Ответ 1

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

def bob():
me = "locally defined" # Defined only in local context
print(me)

bob()
print(me) # Asking for a global variable

Вышесказанное даст вам:

locally defined
Traceback (most recent call last):
File "file.py", line 9, in <module>
print(me)
NameError: name 'me' is not defined

Хотя, если вы используете оператор global, переменная станет доступной "вне" области действия функции, фактически став глобальной переменной.

def bob():
global me
me = "locally defined" # Defined locally but declared as global
print(me)

bob()
print(me) # Asking for a global variable

Итак, приведенный выше код даст вам:

locally defined
locally defined

Кроме того, из-за природы python вы также можете использовать global для объявления функций, классов или других объектов в локальном контексте. Хотя я бы не советовал этого делать, поскольку это вызывает кошмары, если что-то идет не так или требуется отладка.

Ответ 2

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

foo = 1
def test():
foo = 2 # new local foo

def blub():
global foo
foo = 3 # changes the value of the global foo

В вашем случае вы просто обращаетесь к спискуsub.

Ответ 3

В этом разница между доступом к имени и привязкой к нему в области видимости.

Если вы просто ищете переменную, чтобы прочитать ее значение, у вас есть доступ как к глобальной, так и к локальной области видимости.

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

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

Привязка в любом месте внутри блока приводит к тому, что имя везде в этом блоке становится связанным, что может вызвать некоторые довольно странные последствия (например, UnboundLocalError, внезапно появляющийся в ранее работавшем коде).

>>> a = 1
>>> def p():
print(a) # accessing global scope, no binding going on
>>> def q():
a = 3 # binding a name in local scope - hiding global
print(a)
>>> def r():
print(a) # fail - a is bound to local scope, but not assigned yet
a = 4
>>> p()
1
>>> q()
3
>>> r()
Traceback (most recent call last):
File "<pyshell#35>", line 1, in <module>
r()
File "<pyshell#32>", line 2, in r
print(a) # fail - a is bound to local scope, but not assigned yet
UnboundLocalError: local variable 'a' referenced before assignment
>>>
Ответ 4

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

Рассмотрим это, например:

value = 42

def doit():
print value
value = 0

doit()
print value

Вероятно, вы можете догадаться, что value = 0 оператор будет присваивать значение локальной переменной и не повлияет на значение той же переменной, объявленной вне doit() функции. Возможно, вы будете еще больше удивлены, обнаружив, что приведенный выше код не будет выполняться. Оператор print value внутри функции выдает UnboundLocalError.

Причина в том, что Python заметил, что в другом месте функции вы присваиваете имя value, а также value нигде не объявлено global. Это делает ее локальной переменной. Но когда вы пытаетесь его напечатать, локальное имя еще не определено. Python в этом случае не возвращается к поиску имени в качестве глобальной переменной, как это делают некоторые другие языки. По сути, вы не можете получить доступ к глобальной переменной, если вы определили локальную переменную с таким же именем в любом месте функции.

python