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

6 ответов


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

Э. Г.

global someVar
someVar = 55

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

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


в области 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'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. Таким образом, мы имеем:

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 либо, она создает локальную копию, так как это назначение значение.

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


как отмечали другие, вам нужно объявить переменную 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'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

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

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 не повлияло на значение по умолчанию, назначенное param. Отсрочка оценки, как и в следующем, сработала так, как мне было нужно.

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

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

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

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


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

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