376 Stimmen

Globale Variablen für Python-Funktionen?

Ich weiß, ich sollte vermeiden, mit globalen Variablen in erster Linie aufgrund von Verwirrung wie diese, aber wenn ich sie verwenden sollten, ist die folgende eine gültige Art und Weise zu gehen, über die Verwendung von ihnen? (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()

Ist die x die die zweite Funktion verwendet, den gleichen Wert wie die globale Kopie von x dass func_a verwendet und modifiziert? Spielt die Reihenfolge beim Aufruf der Funktionen nach der Definition eine Rolle?

1 Stimmen

Nehmen Sie nicht an, dass Python Referenzen vor der Zuweisung als solche behandelt, nur weil Sie eine Variable in Ihrer Funktion zugewiesen haben. Bis zur ersten Zuweisung, wenn Sie x verwenden, wäre es weder die globale noch die lokale Variable. Sie werden die berüchtigte UnboundLocalError-Ausnahme ins Gesicht bekommen :)

0 Stimmen

Python kopiert nicht im Auftrag.

544voto

Levon Punkte 134187

Wenn Sie einfach auf eine globale Variable zugreifen wollen, verwenden Sie einfach ihren Namen. Um jedoch ändern seinen Wert zu ermitteln, müssen Sie die global Stichwort.

z.B.

global someVar
someVar = 55

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

Die Reihenfolge der Auflistung von Funktionsdefinitionen spielt keine Rolle (vorausgesetzt, sie beziehen sich nicht in irgendeiner Weise aufeinander), die Reihenfolge ihres Aufrufs schon.

148voto

jdotjdot Punkte 15238

Innerhalb eines Python-Bereichs erzeugt jede Zuweisung an eine Variable, die nicht bereits innerhalb dieses Bereichs deklariert wurde, eine neue lokale Variable es sei denn, diese Variable zuvor in der Funktion mit dem Schlüsselwort "global scoped variable" deklariert wurde global .

Schauen wir uns eine geänderte 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

Man könnte sogar alles umschreiben func_B mit der Variablen namens x_local und es würde identisch funktionieren.

Die Reihenfolge spielt nur insofern eine Rolle, als die Funktionen Operationen ausführen, die den Wert des globalen x ändern. In unserem Beispiel spielt die Reihenfolge also keine Rolle, da func_B ruft auf. func_A . In diesem Beispiel spielt die Reihenfolge eine Rolle:

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 ist nur erforderlich, um globale Objekte zu ändern. Sie können immer noch von einer Funktion aus auf sie zugreifen, ohne dass sie deklariert werden müssen. global . Wir haben also:

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 y access_only -- access_only auf das globale x zugreift, obwohl es nicht global und auch wenn create_locally verwendet nicht global erstellt es eine lokale Kopie, da es sich Zuweisung von einen Wert.

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

27voto

Noisy_Botnet Punkte 371

Sie können innerhalb einer Funktion direkt auf eine globale Variable zugreifen. Wenn Sie den Wert dieser globalen Variable ändern wollen, verwenden Sie "globale_Variable_name". Siehe das folgende 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. Wenn die Namespace-Logik durchbrochen wird, kann der Code schwer zu verstehen und zu debuggen sein.

25voto

kindall Punkte 167554

Wie bereits von anderen erwähnt, müssen Sie eine Variable deklarieren global in einer Funktion, wenn diese Funktion die globale Variable ändern soll. Wenn Sie nur auf sie zugreifen wollen, brauchen Sie keine global .

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

Viele Operationen, die ein Objekt verändern (mutieren) nicht den globalen Namen neu binden, so dass er auf ein anderes Objekt verweist, und so sind sie alle gültig ohne den Namen zu deklarieren global in der 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

11voto

SoloPilot Punkte 1381

Hier ist ein Fall, der mir aufgefallen ist, nämlich die Verwendung eines Globals als Standardwert für einen Parameter.

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. Eine Überraschung. Python 2.7 hat den Wert von globVar ausgewertet, als es die Funktion func zum ersten Mal geparst hat. Das Ändern des Wertes von globVar hatte keine Auswirkungen auf den Standardwert von param. Die Verzögerung der Auswertung, wie im Folgenden beschrieben, funktionierte so, wie ich sie brauchte.

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

Oder, wenn Sie auf Nummer sicher gehen wollen,

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X