web-dev-qa-db-de.com

Python Funktion globale Variablen?

Ich weiß, dass ich die Verwendung globaler Variablen wegen dieser Verwirrung zunächst vermeiden sollte, aber wenn ich sie verwenden würde, ist die folgende Vorgehensweise sinnvoll, um sie zu verwenden? (Ich versuche, die globale Kopie einer Variablen aufzurufen, die in einer separaten Funktion erstellt wurde.)

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()

Hat das 'x', das die zweite Funktion verwendet, denselben Wert wie die globale Kopie von 'x', die 'func_a' verwendet und ändert? Kommt es beim Aufruf der Funktionen nach der Definition auf die Reihenfolge an?

246
Akshat Shekhar

Wenn Sie einfach auf eine globale Variable zugreifen möchten, verwenden Sie einfach ihren Namen. Um jedoch den Wert zu ändern , müssen Sie das Schlüsselwort global verwenden.

Z.B.

global someVar
someVar = 55

Dies würde den Wert der globalen Variablen auf 55 ändern. Andernfalls würde nur einer lokalen Variablen 55 zugewiesen.

Die Reihenfolge der Auflistungen von Funktionsdefinitionen spielt keine Rolle (vorausgesetzt, sie verweisen nicht in irgendeiner Weise aufeinander), sondern die Reihenfolge, in der sie aufgerufen werden.

375
Levon

Innerhalb eines Python - Bereichs erstellt jede Zuweisung zu einer Variablen, die nicht bereits in diesem Bereich deklariert ist, eine neue lokale Variable sofern nicht diese Variable in der Funktion zuvor als auf a verweisend deklariert wurde globale Variable mit dem Schlüsselwort global.

Schauen wir uns eine modifizierte Version Ihres Pseudocodes an, um zu sehen, was passiert:

# 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

Tatsächlich könnten Sie func_B Mit der Variablen x_local Umschreiben, und es würde identisch funktionieren.

Die Reihenfolge ist nur so wichtig wie die Reihenfolge, in der Ihre Funktionen Operationen ausführen, die den Wert des globalen x ändern. Daher spielt in unserem Beispiel die Reihenfolge keine Rolle, da func_Bfunc_A Aufruft. In diesem Beispiel ist die Reihenfolge wichtig:

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'.

Beachten Sie, dass global nur zum Ändern globaler Objekte erforderlich ist. Sie können weiterhin von einer Funktion aus darauf zugreifen, ohne global zu deklarieren. So haben wir:

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.

Beachten Sie den Unterschied zwischen create_locally Und access_only - access_only Greift auf das globale x zu, obwohl global nicht aufgerufen wird, und obwohl create_locally Dies nicht tut Auch global wird nicht verwendet. Es wird eine lokale Kopie erstellt, da Zuweisung ein Wert ist.

Die Verwirrung hier ist, warum Sie keine globalen Variablen verwenden sollten.

102
jdotjdot

Wie andere angemerkt haben, müssen Sie eine Variable global in einer Funktion deklarieren, damit diese Funktion die globale Variable ändern kann. Wenn Sie nur darauf zugreifen möchten, benötigen Sie global nicht.

Um dies etwas näher zu erläutern, bedeutet "Ändern" Folgendes: Wenn Sie den globalen Namen erneut binden so dass er auf ein anderes Objekt verweist, muss der Name in global deklariert werden die Funktion.

Viele Operationen, die ein Objekt ändern (mutieren) nicht binden den globalen Namen erneut, um auf ein anderes Objekt zu verweisen, und sind daher alle gültig, ohne den Namen global in zu deklarieren die Funktion.

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
17
kindall

Hier ist ein Fall, der mich überrascht hat, als Standardwert eines Parameters ein Global zu verwenden.

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

Ich hatte erwartet, dass param einen Wert von 42 hat. Überraschung. Python 2.7 hat den Wert von globVar ausgewertet, als die Funktion func zum ersten Mal analysiert wurde. Das Ändern des Werts von globVar hatte keine Auswirkungen auf den Standardwert, der param zugewiesen wurde. Die Auswertung zu verzögern, wie im Folgenden beschrieben, funktionierte so, wie ich es brauchte.

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

Oder, wenn Sie sicher sein wollen,

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

Sie können direkt auf eine globale Variable innerhalb einer Funktion zugreifen. Wenn Sie den Wert dieser globalen Variablen ändern möchten, verwenden Sie "global variable_name". Siehe folgendes Beispiel:

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

Im Allgemeinen ist dies keine gute Programmierpraxis. Durch das Unterbrechen der Namespace-Logik kann es schwierig werden, Code zu verstehen und zu debuggen.

3
Noisy_Botnet

Sie müssen die global -Deklaration verwenden, wenn Sie den einer globalen Variablen zugewiesenen Wert ändern möchten.

Sie brauchen es nicht, um aus einer globalen Variablen zu lesen. Beachten Sie, dass das Aufrufen einer Methode für ein Objekt (auch wenn es die Daten in diesem Objekt ändert) den Wert der Variablen, die dieses Objekt enthält, nicht ändert (ohne reflektierende Magie).

1
Marcin