web-dev-qa-db-de.com

Globale Variablen in einer Funktion verwenden

Wie kann ich eine globale Variable in einer Funktion erstellen oder verwenden?

Wie kann ich eine globale Variable in einer anderen Funktion verwenden, wenn ich sie in einer Funktion erstelle? Muss ich die globale Variable in einer lokalen Variablen der Funktion speichern, auf die zugegriffen werden muss?

2870
user46646

Sie können eine globale Variable in anderen Funktionen verwenden, indem Sie sie in jeder zugewiesenen Funktion als global deklarieren:

globvar = 0

def set_globvar_to_one():
    global globvar    # Needed to modify global copy of globvar
    globvar = 1

def print_globvar():
    print(globvar)     # No need for global declaration to read value of globvar

set_globvar_to_one()
print_globvar()       # Prints 1

Ich stelle mir den Grund dafür vor, dass Python, da globale Variablen so gefährlich sind, sicherstellen möchte, dass Sie wirklich wissen, womit Sie spielen, indem Sie das Schlüsselwort global explizit anfordern.

Sehen Sie sich andere Antworten an, wenn Sie eine globale Variable für mehrere Module freigeben möchten.

3964
Paul Stephenson

Wenn ich Ihre Situation richtig verstehe, wird angezeigt, wie Python mit lokalen (Funktions-) und globalen (Modul-) Namespaces umgeht.

Angenommen, Sie haben ein Modul wie das folgende:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

Sie können davon ausgehen, dass 42 ausgegeben wird, aber es wird stattdessen 5 ausgegeben. Wenn Sie func1() wie bereits erwähnt eine 'global'-Deklaration hinzufügen, wird func2() 42 ausgegeben.

def func1():
    global myGlobal
    myGlobal = 42

Was hier vor sich geht ist, dass Python annimmt, dass jeder Name, der zugewiesen ist , irgendwo innerhalb einer Funktion, für diese Funktion lokal ist sofern nicht ausdrücklich anders angegeben. Wenn nur aus einem Namen gelesen wird und der Name lokal nicht vorhanden ist, wird versucht, den Namen in allen Bereichen nachzuschlagen (z. B. den globalen Geltungsbereich des Moduls).

Wenn Sie dem Namen myGlobal den Wert 42 zuweisen, erstellt Python daher eine lokale Variable, die die globale Variable mit dem gleichen Namen abschattet. Das Lokal verlässt den Gültigkeitsbereich und ist durch Müll gesammelt wenn func1() zurückkehrt; In der Zwischenzeit kann func2() nur den (unveränderten) globalen Namen sehen. Beachten Sie, dass diese Namespace-Entscheidung zur Kompilierungszeit und nicht zur Laufzeit erfolgt. Wenn Sie den Wert von myGlobal in func1() lesen, bevor Sie ihn zuweisen, erhalten Sie UnboundLocalError. , weil Python bereits entschieden hat, dass es sich um eine lokale Variable handeln muss, ihr jedoch noch kein Wert zugeordnet wurde. Mit der Anweisung 'global' teilen Sie Python mit, dass der Name an einer anderen Stelle gesucht werden soll, anstatt ihn lokal zuzuweisen.

(Ich glaube, dass dieses Verhalten größtenteils durch eine Optimierung lokaler Namespaces verursacht wurde. Ohne dieses Verhalten müsste Pythons VM jedes Mal, wenn ein neuer Name in einer Funktion (to) zugewiesen wird, mindestens drei Namenssuchen durchführen Stellen Sie sicher, dass der Name nicht bereits auf Modul-/eingebauter Ebene existiert, was eine sehr häufige Operation erheblich verlangsamen würde.)

732
Jeff Shannon

Vielleicht möchten Sie den Begriff Namespaces untersuchen. In Python ist Modul der natürliche Ort für globale Daten:

Jedes Modul verfügt über eine eigene private Symboltabelle, die von allen im Modul definierten Funktionen als globale Symboltabelle verwendet wird. Auf diese Weise kann der Autor eines Moduls globale Variablen im Modul verwenden, ohne sich Gedanken über versehentliche Konflikte mit den globalen Variablen eines Benutzers machen zu müssen. Wenn Sie dagegen wissen, was Sie tun, können Sie die globalen Variablen eines Moduls mit der gleichen Notation berühren, die für die Verweise auf seine Funktionen verwendet wird: modname.itemname.

Eine spezifische Verwendung von global-in-a-module wird hier beschrieben - Wie teile ich globale Variablen über Module hinweg? , und der Vollständigkeit halber werden die Inhalte hier geteilt:

Die kanonische Methode zum Austausch von Informationen zwischen Modulen innerhalb eines einzelnen Programms besteht darin, ein spezielles Konfigurationsmodul zu erstellen (häufig als config oder cfg bezeichnet). Importieren Sie einfach das Konfigurationsmodul in alle Module Ihrer Anwendung. Das Modul wird dann als globaler Name verfügbar. Da es nur eine Instanz jedes Moduls gibt, werden alle am Modulobjekt vorgenommenen Änderungen überall wiedergegeben. Zum Beispiel:

Datei: config.py

x = 0   # Default value of the 'x' configuration setting

Datei: mod.py

import config
config.x = 1

Datei: main.py

import config
import mod
print config.x
201
gimel

Python verwendet eine einfache Heuristik, um zu entscheiden, aus welchem ​​Bereich eine Variable zwischen lokal und global geladen werden soll. Wird ein Variablenname auf der linken Seite einer Zuweisung angezeigt, aber nicht als global deklariert, wird davon ausgegangen, dass er lokal ist. Wenn es nicht auf der linken Seite einer Zuweisung angezeigt wird, wird angenommen, dass es global ist.

>>> import dis
>>> def foo():
...     global bar
...     baz = 5
...     print bar
...     print baz
...     print quux
... 
>>> dis.disassemble(foo.func_code)
  3           0 LOAD_CONST               1 (5)
              3 STORE_FAST               0 (baz)

  4           6 LOAD_GLOBAL              0 (bar)
              9 PRINT_ITEM          
             10 PRINT_NEWLINE       

  5          11 LOAD_FAST                0 (baz)
             14 PRINT_ITEM          
             15 PRINT_NEWLINE       

  6          16 LOAD_GLOBAL              1 (quux)
             19 PRINT_ITEM          
             20 PRINT_NEWLINE       
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE        
>>> 

Sehen Sie, wie baz, das in foo() auf der linken Seite einer Zuweisung erscheint, die einzige LOAD_FAST -Variable ist.

Wenn Sie in einer Funktion auf eine globale Variable verweisen möchten, können Sie mit dem Schlüsselwort global deklarieren, welche Variablen global sind. Sie müssen es nicht in allen Fällen verwenden (wie hier fälschlicherweise behauptet wird). Wenn der Name, auf den in einem Ausdruck verwiesen wird, in den Funktionen, in denen diese Funktion definiert ist, nicht im lokalen Bereich oder in den Bereichen gefunden werden kann, wird er unter global nachgeschlagen Variablen.

Wenn Sie jedoch eine neue Variable zuweisen, die in der Funktion nicht als global deklariert ist, wird sie implizit als lokal deklariert und kann eine vorhandene globale Variable mit demselben Namen überschatten.

Außerdem sind globale Variablen nützlich, im Gegensatz zu einigen OOP - Eifern, die etwas anderes behaupten - insbesondere bei kleineren Skripten, bei denen OOP zu viel bedeutet.

55
J S

Zusätzlich zu bereits vorhandenen Antworten und um dies noch verwirrender zu machen:

In Python sind Variablen, auf die nur innerhalb einer Funktion verwiesen wird, implizit global. Wenn einer Variablen irgendwo im Funktionskörper ein neuer Wert zugewiesen wird, wird angenommen, dass es sich um ein local handelt. Wenn einer Variablen in der Funktion jemals ein neuer Wert zugewiesen wird, ist die Variable implizit lokal und muss explizit als "global" deklariert werden.

Zunächst etwas überraschend, erklärt dies jedoch eine kurze Überlegung. Einerseits bietet das Erfordernis von global für zugewiesene Variablen einen Schutz vor unbeabsichtigten Nebenwirkungen. Wenn andererseits global für alle globalen Verweise erforderlich wäre, würden Sie global die ganze Zeit verwenden. Sie müssen jeden Verweis auf eine integrierte Funktion oder eine Komponente eines importierten Moduls als global deklarieren. Diese Unordnung würde den Nutzen der globalen Deklaration für die Identifizierung von Nebenwirkungen zunichte machen.

Quelle: Wie lauten die Regeln für lokale und globale Variablen in Python?.

42
Rauni Lillemets

Wie kann ich eine globale Variable in einer anderen Funktion verwenden, wenn ich sie in einer Funktion erstelle?

Wir können eine globale mit der folgenden Funktion erstellen:

def create_global_variable():
    global global_variable # must declare it to be a global first
    # modifications are thus reflected on the module's global scope
    global_variable = 'Foo' 

Das Schreiben einer Funktion führt ihren Code nicht aus. Also rufen wir die Funktion create_global_variable auf:

>>> create_global_variable()

Globale ohne Änderung verwenden

Sie können es einfach verwenden, solange Sie nicht damit rechnen, das Objekt zu ändern, auf das es verweist:

Zum Beispiel,

def use_global_variable():
    return global_variable + '!!!'

und jetzt können wir die globale Variable verwenden:

>>> use_global_variable()
'Foo!!!'

Änderung der globalen Variablen aus einer Funktion heraus

Um die globale Variable auf ein anderes Objekt zu verweisen, müssen Sie das globale Schlüsselwort erneut verwenden:

def change_global_variable():
    global global_variable
    global_variable = 'Bar'

Beachten Sie, dass nach dem Schreiben dieser Funktion der Code, der sie tatsächlich ändert, immer noch nicht ausgeführt wird:

>>> use_global_variable()
'Foo!!!'

Also nach dem Aufruf der Funktion:

>>> change_global_variable()

wir können sehen, dass die globale Variable geändert wurde. Der global_variable Name zeigt jetzt auf 'Bar':

>>> use_global_variable()
'Bar!!!'

Beachten Sie, dass "global" in Python nicht wirklich global ist, sondern nur global für die Modulebene. Es ist also nur für Funktionen verfügbar, die in den Modulen geschrieben wurden, in denen es global ist. Funktionen erinnern sich an das Modul, in dem sie geschrieben wurden. Wenn sie in andere Module exportiert werden, sehen sie weiterhin in dem Modul nach, in dem sie erstellt wurden, um globale Variablen zu finden.

Lokale Variablen mit demselben Namen

Wenn Sie eine lokale Variable mit demselben Namen erstellen, überschattet diese eine globale Variable:

def use_local_with_same_name_as_global():
    # bad name for a local variable, though.
    global_variable = 'Baz' 
    return global_variable + '!!!'

>>> use_local_with_same_name_as_global()
'Baz!!!'

Die Verwendung dieser falsch benannten lokalen Variablen ändert jedoch nicht die globale Variable:

>>> use_global_variable()
'Bar!!!'

Beachten Sie, dass Sie die Verwendung lokaler Variablen mit denselben Namen wie globale Variablen vermeiden sollten, es sei denn, Sie wissen genau, was Sie tun, und Sie haben einen sehr guten Grund dafür. Ich bin noch keinem solchen Grund begegnet.

37
Aaron Hall

Bei der parallelen Ausführung können globale Variablen zu unerwarteten Ergebnissen führen, wenn Sie nicht verstehen, was passiert. Hier ist ein Beispiel für die Verwendung einer globalen Variablen innerhalb von Multiprocessing. Wir können deutlich sehen, dass jeder Prozess mit einer eigenen Kopie der Variablen funktioniert:

import multiprocessing
import os
import random
import sys
import time

def worker(new_value):
    old_value = get_value()
    set_value(random.randint(1, 99))
    print('pid=[{pid}] '
          'old_value=[{old_value:2}] '
          'new_value=[{new_value:2}] '
          'get_value=[{get_value:2}]'.format(
          pid=str(os.getpid()),
          old_value=old_value,
          new_value=new_value,
          get_value=get_value()))

def get_value():
    global global_variable
    return global_variable

def set_value(new_value):
    global global_variable
    global_variable = new_value

global_variable = -1

print('before set_value(), get_value() = [%s]' % get_value())
set_value(new_value=-2)
print('after  set_value(), get_value() = [%s]' % get_value())

processPool = multiprocessing.Pool(processes=5)
processPool.map(func=worker, iterable=range(15))

Ausgabe:

before set_value(), get_value() = [-1]
after  set_value(), get_value() = [-2]
pid=[53970] old_value=[-2] new_value=[ 0] get_value=[23]
pid=[53971] old_value=[-2] new_value=[ 1] get_value=[42]
pid=[53970] old_value=[23] new_value=[ 4] get_value=[50]
pid=[53970] old_value=[50] new_value=[ 6] get_value=[14]
pid=[53971] old_value=[42] new_value=[ 5] get_value=[31]
pid=[53972] old_value=[-2] new_value=[ 2] get_value=[44]
pid=[53973] old_value=[-2] new_value=[ 3] get_value=[94]
pid=[53970] old_value=[14] new_value=[ 7] get_value=[21]
pid=[53971] old_value=[31] new_value=[ 8] get_value=[34]
pid=[53972] old_value=[44] new_value=[ 9] get_value=[59]
pid=[53973] old_value=[94] new_value=[10] get_value=[87]
pid=[53970] old_value=[21] new_value=[11] get_value=[21]
pid=[53971] old_value=[34] new_value=[12] get_value=[82]
pid=[53972] old_value=[59] new_value=[13] get_value=[ 4]
pid=[53973] old_value=[87] new_value=[14] get_value=[70]
31
Bohdan

Wie sich herausstellt, ist die Antwort immer einfach.

Hier ist ein kleines Beispielmodul mit einer einfachen Möglichkeit, es in einer main -Definition anzuzeigen:

def five(enterAnumber,sumation):
    global helper
    helper  = enterAnumber + sumation

def isTheNumber():
    return helper

So zeigen Sie es in einer main -Definition an:

import TestPy

def main():
    atest  = TestPy
    atest.five(5,8)
    print(atest.isTheNumber())

if __== '__main__':
    main()

Dieser einfache Code funktioniert genauso und wird ausgeführt. Ich hoffe, es hilft.

22
user2876408

Was Sie sagen, ist die Methode wie folgt zu verwenden:

globvar = 5

def f():
    var = globvar
    print(var)

f()  # Prints 5

Der bessere Weg ist jedoch, die globale Variable wie folgt zu verwenden:

globavar = 5
def f():
    global globvar
    print(globvar)
f()   #prints 5

Beide geben die gleiche Ausgabe.

21
gxyd

Sie müssen in jeder Funktion, die Sie verwenden möchten, auf die globale Variable verweisen.

Wie folgt:

var = "test"

def printGlobalText():
    global var #wWe are telling to explicitly use the global version
    var = "global from printGlobalText fun."
    print "var from printGlobalText: " + var

def printLocalText():
    #We are NOT telling to explicitly use the global version, so we are creating a local variable
    var = "local version from printLocalText fun"
    print "var from printLocalText: " + var

printGlobalText()
printLocalText()
"""
Output Result:
var from printGlobalText: global from printGlobalText fun.
var from printLocalText: local version from printLocalText
[Finished in 0.1s]
"""
20
Mohamed El-Saka

Sie speichern das globale Objekt nicht in einer lokalen Variablen, sondern erstellen lediglich einen lokalen Verweis auf dasselbe Objekt, auf das sich Ihr ursprünglicher globaler Verweis bezieht. Denken Sie daran, dass so ziemlich alles in Python ein Name ist, der sich auf ein Objekt bezieht, und dass im normalen Betrieb nichts kopiert wird.

Wenn Sie nicht explizit angeben müssen, wann ein Bezeichner auf einen vordefinierten globalen Wert verweisen soll, müssen Sie vermutlich explizit angeben, wann ein Bezeichner eine neue lokale Variable ist (z. B. mit dem Befehl 'var') gesehen in JavaScript). Da lokale Variablen in allen seriösen und nicht trivialen Systemen häufiger vorkommen als globale Variablen, ist Pythons System in den meisten Fällen sinnvoller.

Sie haben könnten eine Sprache, die versucht hat zu erraten, eine globale Variable zu verwenden, falls vorhanden, oder eine lokale Variable zu erstellen, falls nicht. Dies wäre jedoch sehr fehleranfällig. Wenn Sie beispielsweise ein anderes Modul importieren, wird möglicherweise versehentlich eine globale Variable mit diesem Namen eingefügt, wodurch sich das Verhalten Ihres Programms ändert.

18
Kylotan

Versuche dies:

def x1():
    global x
    x = 6

def x2():
    global x
    x = x+1
    print x

x = 5
x1()
x2()  # output --> 7
15
Sagar Mehta

Verwenden Sie nach und als Add-On eine Datei, um alle globalen Variablen zu enthalten, die alle lokal deklariert wurden, und dann import as:

Datei initval.py:

Stocksin = 300
Prices = []

Datei getstocks.py:

import initval as iv

def getmystocks(): 
    iv.Stocksin = getstockcount()


def getmycharts():
    for ic in range(iv.Stocksin):
12
user5473311

Falls Sie eine lokale Variable mit demselben Namen haben, können Sie die Funktion globals() verwenden.

globals()['your_global_var'] = 42
12
Martin Thoma

Das Schreiben in explizite Elemente eines globalen Arrays erfordert anscheinend nicht die globale Deklaration, obwohl das Schreiben in "wholesale" diese Anforderung erfüllt:

import numpy as np

hostValue = 3.14159
hostArray = np.array([2., 3.])
hostMatrix = np.array([[1.0, 0.0],[ 0.0, 1.0]])

def func1():
    global hostValue    # mandatory, else local.
    hostValue = 2.0

def func2():
    global hostValue    # mandatory, else UnboundLocalError.
    hostValue += 1.0

def func3():
    global hostArray    # mandatory, else local.
    hostArray = np.array([14., 15.])

def func4():            # no need for globals
    hostArray[0] = 123.4

def func5():            # no need for globals
    hostArray[1] += 1.0

def func6():            # no need for globals
    hostMatrix[1][1] = 12.

def func7():            # no need for globals
    hostMatrix[0][0] += 0.33

func1()
print "After func1(), hostValue = ", hostValue
func2()
print "After func2(), hostValue = ", hostValue
func3()
print "After func3(), hostArray = ", hostArray
func4()
print "After func4(), hostArray = ", hostArray
func5()
print "After func5(), hostArray = ", hostArray
func6()
print "After func6(), hostMatrix = \n", hostMatrix
func7()
print "After func7(), hostMatrix = \n", hostMatrix
11
Mike Lampton

Ich füge dies hinzu, da ich es in keiner der anderen Antworten gesehen habe, und es könnte für jemanden nützlich sein, der mit etwas Ähnlichem zu kämpfen hat. Die Funktion globals() gibt ein veränderbares globales Symbolwörterbuch zurück, in dem Sie Daten auf magische Weise für den Rest Ihres Codes verfügbar machen können. Zum Beispiel:

from pickle import load
def loaditem(name):
    with open(r"C:\pickle\file\location"+"\{}.dat".format(name), "rb") as openfile:
        globals()[name] = load(openfile)
    return True

und

from pickle import dump
def dumpfile(name):
    with open(name+".dat", "wb") as outfile:
        dump(globals()[name], outfile)
    return True

Lässt Sie nur Variablen aus und in den globalen Namespace ausgeben/laden. Super praktisch, kein Muss, keine Aufregung. Ich bin mir ziemlich sicher, dass es nur Python 3 ist.

5
Rafaël Dera

Verweisen Sie auf den Klassennamensraum, in dem die Änderung angezeigt werden soll.

In diesem Beispiel verwendet runner max aus der Dateikonfiguration. Ich möchte, dass mein Test den Wert von max ändert, wenn der Läufer ihn verwendet.

main/config.py

max = 15000

main/runner.py

from main import config
def check_threads():
    return max < thread_count 

tests/runner_test.py

from main import runner                # <----- 1. add file
from main.runner import check_threads
class RunnerTest(unittest):
   def test_threads(self):
       runner.max = 0                  # <----- 2. set global 
       check_threads()
5
llewellyn falco