Глобальные переменные функции Python?

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

x = "somevalue"

def func_A ():
   global x
   # Do things to x
   return x

def func_B():
   x=func_A()
   # Do things
   return x

func_A()
func_B()

Имеет ли "x", используемое второй функцией, то же значение глобальной копии "x", которое "func_a" использует и изменяет? При вызове функций после определения имеет ли значение порядок?

Ответ 1

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

например.

global someVar
someVar = 55

Это изменит значение глобальной переменной на 55. В противном случае она просто назначит 55 локальной переменной.

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

Ответ 2

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

Посмотрите на измененную версию вашего псевдокода, чтобы узнать, что произойдет:

# Here, we're creating a variable 'x', in the __main__ scope.
x = 'None!'

def func_A():
  # The below declaration lets the function know that we
  #  mean the global 'x' when we refer to that variable, not
  #  any local one

  global x
  x = 'A'
  return x

def func_B():
  # Here, we are somewhat mislead.  We're actually involving two different
  #  variables named 'x'.  One is local to func_B, the other is global.

  # By calling func_A(), we do two things: we're reassigning the value
  #  of the GLOBAL x as part of func_A, and then taking that same value
  #  since it returned by func_A, and assigning it to a LOCAL variable
  #  named 'x'.     
  x = func_A() # look at this as: x_local = func_A()

  # Here, we're assigning the value of 'B' to the LOCAL x.
  x = 'B' # look at this as: x_local = 'B'

  return x # look at this as: return x_local

Фактически, вы можете переписать все func_B с переменной с именем x_local, и она будет работать тождественно.

Порядок имеет значение только в том порядке, в котором ваши функции выполняют операции, которые изменяют значение глобального x. Таким образом, в нашем примере порядок не имеет значения, так как func_B вызывает func_A. В этом примере порядок имеет значение:

def a():
  global foo
  foo = 'A'

def b():
  global foo
  foo = 'B'

b()
a()
print foo
# prints 'A' because a() was the last function to modify 'foo'.

Обратите внимание, что global требуется только для изменения глобальных объектов. Вы можете получить доступ к ним изнутри функции без объявления global. Таким образом, имеем:

x = 5

def access_only():
  return x
  # This returns whatever the global value of 'x' is

def modify():
  global x
  x = 'modified'
  return x
  # This function makes the global 'x' equal to 'modified', and then returns that value

def create_locally():
  x = 'local!'
  return x
  # This function creates a new local variable named 'x', and sets it as 'local',
  #  and returns that.  The global 'x' is untouched.

Обратите внимание, что разница между create_locally и access_only - access_only является доступ к глобальному x, несмотря на то, что не вызывает global, и даже если create_locally не использует global, он создает локальный копировать, поскольку он присваивает значение.

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

Ответ 3

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

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

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

d = {}
l = []
o = type("object", (object,), {})()

def valid():     # these are all valid without declaring any names global!
   d[0] = 1      # changes what in d, but d still points to the same object
   d[0] += 1     # ditto
   d.clear()     # ditto! d is now empty but it`s still the same object!
   l.append(0)   # l is still the same list but has an additional member
   o.test = 1    # creating new attribute on o, but o is still the same object

Ответ 4

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

globVar = None    # initialize value of global variable

def func(param = globVar):   # use globVar as default value for param
    print 'param =', param, 'globVar =', globVar  # display values

def test():
    global globVar
    globVar = 42  # change value of global
    func()

test()
=========
output: param = None, globVar = 42

Я ожидал, что параметр будет иметь значение 42. Сюрприз. Python 2.7 оценил значение globVar, когда он сначала проанализировал функцию func. Изменение значения globVar не повлияло на значение по умолчанию, присвоенное параметру. Отсрочка оценки, как и в следующем, работала так, как мне было нужно.

def func(param = eval('globVar')):       # this seems to work
    print 'param =', param, 'globVar =', globVar  # display values

Или, если вы хотите быть в безопасности,

def func(param = None)):
    if param == None:
        param = globVar
    print 'param =', param, 'globVar =', globVar  # display values

Ответ 5

Вы можете напрямую обращаться к глобальной переменной внутри функции. Если вы хотите изменить значение этой глобальной переменной, используйте "global variable_name". См. Следующий пример:

var = 1
def global_var_change():
      global var
      var = "value changed"
global_var_change() #call the function for changes
print var

Вообще говоря, это не хорошая практика программирования. Разбирая логику пространства имен, код может стать трудным для понимания и отладки.

Ответ 6

Вы должны использовать объявление global, если хотите изменить значение, присвоенное глобальной переменной.

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