Использование «глобального» ключевого слова в Python - PullRequest
270 голосов
/ 14 января 2011

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

Я использую Python 2.7 и попробовал этот маленький тест

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

Кажется, что все работает нормально даже без global. Я смог получить доступ к глобальной переменной без каких-либо проблем.

Я что-то упустил? Также из документации по Python следует:

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

В то время как формальные параметры и определение класса имеют для меня смысл, я не могу понять ограничение для цели управления циклом и определения функции.

Ответы [ 10 ]

348 голосов
/ 14 января 2011

Ключевое слово 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 для объявления функций, классов или других объектов в локальном контексте.Хотя я бы посоветовал против этого, так как это вызывает кошмары, если что-то идет не так или требуется отладка.

201 голосов
/ 14 января 2011

Хотя вы можете получить доступ к глобальным переменным без ключевого слова 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.

69 голосов
/ 14 января 2011

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

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

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

Если вы хотите иметь возможность назначить глобальное имя, вы должны указать парсеру использовать глобальное имя, а не привязывать новое локальное имя - это то, что делает ключевое слово «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
>>> 
48 голосов
/ 14 января 2011

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

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

value = 42

def doit():
    print value
    value = 0

doit()
print value

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

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

13 голосов
/ 14 января 2011

Доступ к имени и присвоение имени отличаются.В вашем случае вы просто получаете доступ к имени.

Если вы присваиваете переменную внутри функции, эта переменная считается локальной, если вы не объявили ее глобальной.В отсутствие этого он считается глобальным.

>>> x = 1         # global 
>>> def foo():
        print x       # accessing it, it is global

>>> foo()
1
>>> def foo():   
        x = 2        # local x
        print x 

>>> x            # global x
1
>>> foo()        # prints local x
2
6 голосов
/ 05 мая 2014
  • Вы можете получить доступ к глобальным ключевым словам без ключевого слова global
  • Чтобы иметь возможность их изменять, вам необходимо явно указать, что ключевое слово является глобальным.В противном случае ключевое слово будет объявлено в локальной области.

Пример:

words = [...] 

def contains (word): 
    global words             # <- not really needed
    return (word in words) 

def add (word): 
    global words             # must specify that we're working with a global keyword
    if word not in words: 
        words += [word]
2 голосов
/ 14 января 2011

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

0 голосов
/ 09 марта 2018

Я приведу простой пример: подумайте об этом коде:

myVar = 0 
print (myVar )      # 01 line: returns 0

def func():
    myVar  = "def"
    print (myVar )

func()              # 02 line: returns def
print (myVar )      # 03 line: returns 0

, как вы видите, последняя строка кода вернет 0, потому что внутри функции myVar переменная не была переназначена, она только что была изменена, и она изменит только тогда, когда функция вызвана без влияния на основную переменную myVar, потому что она определена внутри нашей функции (означает, что это локальная переменная) , но с использованиемключевое слово global как таковое:

 myVar  = 0 
print (myVar )       # 01 Line : returns 0

def func():
    global myVar 
    myVar  = "def"
    print (myVar )

func()               # 02 Line : returns def
print (myVar )       # 03 Line : returns def

мы на самом деле упорядочиваем python, чтобы эта переменная внутри def не была локальной, используйте глобальную переменную с именем myVar , чтобы изменить ее.

0 голосов
/ 07 февраля 2017

Global делает переменную "Global"

def out():
    global x
    x = 1
    print(x)
    return


out()

print (x)

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

def out():
     # Taking out the global will give you an error since the variable x is no longer 'global' or in other words: accessible for other commands
    x = 1
    print(x)
    return


out()

print (x)
0 голосов
/ 14 января 2011

Это означает, что вы не должны делать следующее:

x = 1

def myfunc():
  global x

  # formal parameter
  def localfunction(x):
    return x+1

  # import statement
  import os.path as x

  # for loop control target
  for x in range(10):
    print x

  # class definition
  class x(object):
    def __init__(self):
      pass

  #function definition
  def x():
    print "I'm bad"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...