Verwendung von globalen Variablen in einer Funktion
-
05-07-2019 - |
Frage
Wie kann ich erstellen oder eine globale Variable in einer Funktion verwenden?
Wenn ich eine globale Variable in einer Funktion erstellen, wie kann ich, dass die globale Variable in einer anderen Funktion? Muss ich die globale Variable in einer lokalen Variablen der Funktion speichern müssen, die den Zugang braucht?
Lösung
Sie können eine globale Variable in anderen Funktionen nutzen, indem sie als global
in jeder Funktion erklärt, die ihm zugewiesen:
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 der Grund dafür ist, dass, da globale Variablen so gefährlich sind, Python sicherstellen will, dass Sie wirklich wissen, dass das, was mit ihr spielt, indem das global
Schlüsselwort explizit erforderlich ist.
Sehen Sie andere Antworten, wenn Sie eine globale Variable über Module gemeinsam nutzen möchten.
Andere Tipps
Wenn ich Ihre Situation richtig zu verstehen, was Sie sehen, ist das Ergebnis, wie Python behandelt lokale (Funktion) und global (Modul) Namespaces.
Sagen Sie bitte ein Modul wie diese haben:
# sample.py
myGlobal = 5
def func1():
myGlobal = 42
def func2():
print myGlobal
func1()
func2()
Sie können erwarten dies 42 zu drucken, sondern druckt es 5. Wie bereits erwähnt wurde, wenn Sie eine ‚global
‘ Erklärung in den func1()
, dann wird func2()
42 gedruckt werden.
def func1():
global myGlobal
myGlobal = 42
Was ist hier los ist, dass Python geht davon aus, dass jeder Name, der ist zugewiesen , an jedem Ort innerhalb einer Funktion, um diese Funktion lokal ist, wenn nichts anderes ausdrücklich gesagt. Wenn es nur Lesen von einem Namen, und der Name existiert nicht lokal, werden versuchen, den Namen in irgendwelchen enthält Bereiche zu sehen (zum Beispiel die globale Reichweite des Moduls).
Wenn Sie 42 auf den Namen myGlobal
zuweisen, daher erstellt Python eine lokale Variable, die die globale Variable mit dem gleichen Namen Schatten. Das lokale den Gültigkeitsbereich verlässt und ist Garbage Collection wenn func1()
zurückkehrt; Inzwischen func2()
kann nie etwas anderes als die (nicht modifiziert) globalen Namen. Beachten Sie, dass dieser Namespace Entscheidung bei der Kompilierung der Fall ist, nicht zur Laufzeit - wenn Sie den Wert von myGlobal
innerhalb func1()
zu lesen waren, bevor Sie es zuweisen, dann würden Sie eine UnboundLocalError
bekommen, weil Python bereits entschieden hat, dass es sich um eine lokale sein muss Variable, aber es hat keinen Wert mit ihr noch zugeordnet hat. Aber durch die ‚global
‘ Anweisung, sagen Sie Python, dass es für den Namen woanders suchen sollte, anstatt lokal zuweisen.
(ich glaube, dass dieses Verhalten weitgehend durch eine Optimierung der lokalen Namensräume entstanden - ohne dieses Verhalten, Pythons VM würde mindestens drei Namen jedes Mal Lookups ausführen müssen, um einen neuen Namen innerhalb einer Funktion zugeordnet ist (um sicherzustellen, dass die Name nicht schon existiert im Modul / builtin-Ebene), die deutlich eine sehr häufige Operation verlangsamen würde.)
Sie möchten den Begriff der Namensräume erkunden. In Python, das Modul ist der natürliche Ort für global Daten:
Jedes Modul verfügt über einen eigenen Symboltabelle, die als globale Symboltabelle im Modul von allen Funktionen verwendet wird. So kann der Autor eines Moduls globale Variablen im Modul verwenden, ohne sich Gedanken über die versehentliche Zusammenstöße mit den globalen Variablen des Benutzers. Auf der anderen Seite, wenn Sie wissen, was Sie tun, Sie einen Moduls globale Variablen mit der gleichen Notation, um ihre Funktionen beziehen berühren können,
modname.itemname
.
Eine spezifische Verwendung von global-in-a-Modul wird hier beschrieben - Wie kann ich globale Variablen über Module teilen , und auf Vollständigkeit werden die Inhalte geteilt hier:
Die kanonische Weise Informationen über Module in einem einzigen Programm zu teilen, ist ein spezielles Konfigurationsmodul (oft als Konfiguration oder cfg ) zu erstellen. Importieren Sie einfach das Konfigurationsmodul in allen Modulen der Anwendung; das Modul wird dann als globaler Namen zur Verfügung. Da es nur eine Instanz jedes Moduls ist, werden alle Änderungen an das Modul Objekt erhalten überall reflektiert. 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
Python verwendet eine einfache Heuristik zu entscheiden, welche Tragweite es eine Variable aus, zwischen lokalen und globalen laden soll. Wenn ein Variablenname auf der linken Seite einer Zuweisung erscheint, ist aber nicht global deklariert, wird angenommen, lokal zu sein. Wenn es auf der linken Seite einer Zuweisung nicht erscheint, wird angenommen, global zu sein.
>>> 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, der auf der linken Seite einer Zuweisung in foo()
erscheint, ist der einzige LOAD_FAST
variabel ist.
Wenn Sie auf eine globale Variable in einer Funktion beziehen möchten, können Sie die global verwenden Schlüsselwort zu erklären, welche Variablen global sind. Sie müssen es nicht in allen Fällen verwendet werden (wie hier jemand falsch behauptet) - wenn der Name in einem Ausdruck verwiesen wird, kann nicht in lokalem Bereich oder Bereichen in den Funktionen, in denen diese Funktion definiert ist zu finden, ist es unter dem globalen nachgeschlagen wird Variablen.
Wenn Sie jedoch auf eine neue Variable zuweisen nicht als global in der Funktion deklariert, wird sie implizit als lokale erklärt, und es kann eine vorhandene globale Variable mit dem gleichen Namen beschatten.
Auch globale Variablen sind nützlich, im Gegensatz zu einigen OOP Eiferer, die das Gegenteil behaupten -. Vor allem für kleinere Skripte, wo OOP Overkill ist
Zusätzlich zu bereits bestehenden Antworten und macht dies eher verwirrend:
In Python, Variablen, die nur innerhalb einer Funktion referenziert ist implizit globale . Wird eine Variable einen neuen Wert überall zugewiesen innerhalb der Körpers der Funktion, es ist angenommen, ein lokale sein. Wenn eine Variable wird immer einen neuen Wert innerhalb der Funktion zugewiesen ist, ist die Variable implizit lokal, und Sie müssen es ausdrücklich erklären, als ‚global‘.
Obwohl ein wenig überraschend zunächst eine Betrachtung Moment erklärt diese. Auf der einen Seite für die zugewiesenen Variablen global erfordern bietet eine Stab gegen unbeabsichtigte Nebenwirkungen. Auf der anderen Seite, wenn die globale war erforderlich für alle globalen Referenzen, dann würden Sie global alle werden mit der Zeit. Sie müßten als globales jede Bezugnahme auf einen integrierten in erklären Funktion oder auf eine Komponente eines eingeführten Moduls. Diese Unordnung würde besiegen die Nützlichkeit der globalen Erklärung zur Identifizierung Nebenwirkungen.
Quelle: Was sind die Regeln für die lokale und globale Variablen in Python? .
Wenn ich eine globale Variable in einer Funktion erstellen, wie kann ich diese Variable in einer anderen Funktion?
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'
eine Funktion Schreiben nicht wirklich seinen Code ausführen. So nennen wir die create_global_variable
Funktion:
>>> create_global_variable()
Mit Globals ohne Änderungen
Sie können es einfach, nutzen, solange Sie nicht ändern erwarten, auf die das Objekt verweist er auf:
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 dem Inneren einer Funktion
Um die globale Variable an einem anderen Objekt zu zeigen, sind Sie verpflichtet, wieder das Schlüsselwort global zu verwenden:
def change_global_variable():
global global_variable
global_variable = 'Bar'
Beachten Sie, dass diese Funktion nach dem Schreiben tatsächlich eine Änderung des Codes hat es noch nicht ausgeführt:
>>> use_global_variable()
'Foo!!!'
So nach dem Aufruf der Funktion:
>>> change_global_variable()
Wir können sehen, dass die globale Variable geändert wurde. Der global_variable
Name zeigt nun auf 'Bar'
:
>>> use_global_variable()
'Bar!!!'
Beachten Sie, dass „global“ in Python nicht wirklich global ist - es ist nur global auf Modulebene. So ist es nur auf Funktionen in den Modulen geschrieben, in dem sie global ist. Funktionen erinnern, das Modul, in dem sie geschrieben sind, so dass, wenn sie in anderen Modulen exportiert werden, suchen sie nach wie vor in dem Modul, in dem sie globale Variablen finden erstellt wurden.
Lokale Variablen mit dem gleichen Namen
Wenn Sie eine lokale Variable mit dem gleichen Namen erstellen, wird es eine globale Variable beschatten:
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!!!'
Aber der misnamed lokalen Variable verwendet, nicht die globale Variable ändern:
>>> use_global_variable()
'Bar!!!'
Beachten Sie, dass Sie sollten mit den lokalen Variablen mit dem gleichen Namen wie Globals vermeiden, wenn Sie genau wissen, was Sie tun und haben einen sehr guten Grund, dies zu tun. Ich habe noch nicht auf so einen Grund.
Mit der parallelen Ausführung können globale Variablen zu unerwarteten Ergebnissen führen, wenn Sie nicht verstehen, was geschieht. Hier ist ein Beispiel einer globale Variable innerhalb Multiprozessing zu verwenden. Wir können deutlich sehen, dass jeder Prozess mit seiner eigenen Kopie der Variablen arbeitet:
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))
Ausgang:
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]
Wie die Antwort stellt sich heraus, ist immer einfach.
Hier ist ein kleines Beispiel-Modul mit einem einfachen Weg, um es in einer main
Definition zu zeigen:
def five(enterAnumber,sumation):
global helper
helper = enterAnumber + sumation
def isTheNumber():
return helper
Hier ist, wie es in einer main
Definition zeigen:
import TestPy
def main():
atest = TestPy
atest.five(5,8)
print(atest.isTheNumber())
if __name__ == '__main__':
main()
Dieser einfache Code funktioniert genauso wie das, und es wird ausgeführt. Ich hoffe, es hilft.
Was Sie sagen, ist die Methode wie folgt zu verwenden:
globvar = 5
def f():
var = globvar
print(var)
f() # Prints 5
Aber der bessere Weg ist es, die globale Variable wie folgt zu verwenden:
globavar = 5
def f():
global globvar
print(globvar)
f() #prints 5
Beide geben die gleiche Ausgabe.
Sie müssen die globale Variable in jeder Funktion verweisen Sie verwenden möchten.
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]
"""
Sie speichert nicht tatsächlich die globale in einer lokalen Variablen, nur einen lokalen Bezug auf das gleiche Objekt erstellen, die Ihre ursprüngliche globale Referenz bezieht sich auf. Denken Sie daran, dass so ziemlich alles in Python ein Name auf ein Objekt bezieht, ist, und nichts wird in üblichem Betrieb kopiert.
Wenn Sie nicht explizit haben zu spezifizieren, wenn eine Kennung auf einen vordefinierten globalen Bezug zu nehmen ist, dann würden Sie vermutlich müssen explizit angeben, wenn eine Kennung eine neue lokale Variable ist statt (zum Beispiel mit so etwas wie die ' var‘Befehl in JavaScript zu sehen). Da lokale Variablen häufiger als globale Variablen in einer schweren und nicht-trivialen System sind, Python System mehr Sinn in den meisten Fällen macht.
Sie könnte haben eine Sprache, die unter Verwendung einer globalen Variablen zu erraten versucht, wenn es eine lokale Variable existiert oder das Erstellen, wenn es nicht tat. Das wäre jedoch sehr fehleranfällig. Zum Beispiel vorstellt versehentlich eine globale Variable mit diesem Namen könnte ein anderes Modul zu importieren, um das Verhalten des Programms zu ändern.
Versuchen Sie folgendes:
def x1():
global x
x = 6
def x2():
global x
x = x+1
print x
x = 5
x1()
x2() # output --> 7
Falls Sie eine lokale Variable mit dem gleichen Namen haben, könnten Sie die
Im Anschluss an und als schöne Ergänzung, verwenden Sie eine Datei, die alle globalen Variablen enthalten alle lokal deklariert und dann Datei initval.py : Datei getstocks.py : import as
: Stocksin = 300
Prices = []
import initval as iv
def getmystocks():
iv.Stocksin = getstockcount()
def getmycharts():
for ic in range(iv.Stocksin):
Schreiben auf explizite Elemente einer globalen Array offenbar nicht die globale Deklaration müssen, obwohl es zu schreiben „Großhandel“ hat diese Anforderung:
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
Referenz der Klasse Namespace, wo Sie die Änderung wollen sich zeigen.
In diesem Beispiel Läufer werden mit max aus der Datei config. Ich möchte meinen Test den Wert von max ändern, wenn Läufer verwendet es.
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()
Ich bin, diese, wie ich es nicht in eine der anderen Antworten gesehen haben und es könnte für jemanden kämpfen mit etwas ähnlich nützlich sein. Die globals()
Funktion gibt einen wandelbaren Wörterbuch globales Symbol in dem Sie „magische Weise“ machen Daten für den Rest des Codes zur Verfügung.
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
Wird nur lassen Sie Dump / Lastvariablen aus und in den globalen Namespace. Super bequem, kein Durcheinander, kein Stress. Ziemlich sicher, dass es Python 3 nur.