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 использует и модифицирует? При вызове функций после определения имеет ли значение порядок?

Ответы на вопрос(6)

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

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

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

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

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

Я ожидал, что param будет иметь значение 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
Решение Вопроса

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

Например.

global someVar
someVar = 55

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

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

В пределах области Python любое присвоение переменной, еще не объявленной в этой области, создает новую локальную переменнуюunless эта переменная была объявлена ранее в функции как ссылка на глобальную переменную с ключевым словом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's 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. Thus, we have:

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 получает доступ к глобальной х, несмотря на то, что не звонитglobalи хотяcreate_locally не используетglobal либо он создает локальную копию, так как онassigning ценность.

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

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

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

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

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

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

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

def valid():     # these are all valid without declaring any names global!
   d[0] = 1      # changes what's 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

Ваш ответ на вопрос