Heim > Artikel > Backend-Entwicklung > Eine Reihe von Problemen, die durch die Verwendung von GLOBAL in PYTHON verursacht werden
Was schief gelaufen ist
In Python werden durch die Verwendung von global globale Variablen für diese Funktion verfügbar gemacht. Gleichzeitig erfolgt der Zugriff auf Variablen innerhalb einer Funktion zunächst lokal und dann global.
In verschachtelten Funktionen führt die Verwendung von global zu unangemessenem Verhalten.
Oberer Code:
In [96]: def x(): b = 12 def y(): global a,b a = 1 b = 2 y() print "b =",b ....: In [97]: a = 111 In [98]: del b In [99]: x() b = 12 In [100]: a Out[100]: 1 In [101]: b Out[101]: 2
In der Funktion x() wird global nicht verwendet, und b verwendet zu diesem Zeitpunkt lokal. Print druckt also lokales b
Warum wird 12 gedruckt? Und wie lässt sich erklären, dass b in In[101] 2 ist?
y(), das verwendete Global importiert nicht b = 12 von x().
In der Funktion y() erweitert die Anweisung global a,b a und b zu global, sodass auf der höchsten Ebene b (In[101]) vorhanden ist, selbst wenn kein b (In[98]) vorhanden ist generiert.
Mit anderen Worten: Global a,b betrachtet a und b als die äußersten Variablen.
Versuchen Sie es erneut:
In [102]: def x(): b = 12 def y(): global a,b a = 1 y() print "b =",b .....: In [103]: a = 111 In [104]: del b In [105]: x() b = 12 In [106]: a Out[106]: 1 In [107]: b --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-107-3b5d5c371295> in <module>() ----> 1 b NameError: name 'b' is not defined
Es wurde ein Fehler gemeldet! Wenn nach y() global b keine Zuweisung erfolgt, gibt es auf der obersten Ebene kein b. Dies zeigt, dass global nur Namen einführt und keine Vorgänge wie Zuweisungen ausführt.
Global ist es egal, ob die Variable existiert oder nicht, es importiert nur den Namen und Operationen mit dem Namen werden im „Namespace der obersten Ebene“ widergespiegelt.
Komm wieder:
In [109]: a = 111 In [110]: del b --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-110-745f2abe7045> in <module>() ----> 1 del b NameError: name 'b' is not defined In [111]: def x(): b = 12 def y(): global a,b a = 1 print b y() print "b =",b .....: In [112]: x() --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-112-7354d77c61ac> in <module>() ----> 1 x() <ipython-input-111-c05fc67a1e82> in x() 5 a = 1 6 print b ----> 7 y() 8 print "b =",b 9 <ipython-input-111-c05fc67a1e82> in y() 4 global a,b 5 a = 1 ----> 6 print b 7 y() 8 print "b =",b NameError: global name 'b' is not defined
Dies bestätigt, dass die globale Ebene der inneren Ebene y() keine Dinge von x() importiert.
Wie verwendet die innere Funktion also die richtigen Variablen der äußeren Funktion?
Lösung des Problems der Übergabe innerer Funktionsparameter
1.
Erstens: Wenn Sie nur den Wert erhalten, müssen Sie keine Verarbeitung durchführen.
In [119]: def x(): .....: a = 12 .....: def y(): .....: print a .....: y() .....: In [120]: x() 12 In [121]:
Sobald a in y() ein Wert zugewiesen wird, wird a sofort zu einer internen Variablen.
In [121]: def x(): .....: a = 12 .....: def y(): .....: print "before a =",a .....: a = 1 .....: print "then a =",a .....: y() .....: In [122]: x() before a =--------------------------------------------------------------------------- UnboundLocalError Traceback (most recent call last) <ipython-input-122-7354d77c61ac> in <module>() ----> 1 x() <ipython-input-121-d8fbc0dba399> in x() 5 a = 1 6 print "then a =",a ----> 7 y() 8 <ipython-input-121-d8fbc0dba399> in y() 2 a = 12 3 def y(): ----> 4 print "before a =",a 5 a = 1 6 print "then a =",a UnboundLocalError: local variable 'a' referenced before assignment
Sobald a irgendwo in der Funktion y() ein Wert zugewiesen wird, geht Python vor der Zuweisung davon aus, dass a nicht existiert.
Gleichzeitig habe ich festgestellt, dass der Druck von Python2 nacheinander ausgegeben wird. Aus diesem Grund habe ich es erneut in Python3 versucht und festgestellt, dass es zusammen ausgegeben wurde. Da dies jedoch nicht der Schwerpunkt dieses Artikels ist, falte ich ihn.
In [7]: def x(): a = 1 def y(): print("before a=",a) a = 10 print("then a=",a) y() ...: In [8]: x() --------------------------------------------------------------------------- UnboundLocalError Traceback (most recent call last) <ipython-input-8-7354d77c61ac> in <module>() ----> 1 x() <ipython-input-7-6e01e7317b24> in x() a = 10 print("then a=",a) ----> 7 y() <ipython-input-7-6e01e7317b24> in y() a = 1 def y(): ----> 4 print("before a=",a) a = 10 print("then a=",a) UnboundLocalError: local variable 'a' referenced before assignment
Gleichzeitig habe ich festgestellt, dass der Code vor der Ausführung des Python-Codes zuerst gescannt und nicht einfach Zeile für Zeile ausgeführt wird.
Es wurde auch festgestellt, dass UnboundLocalError anstelle von NameError zurückgegeben wird. Beachten Sie „ungebunden“, was das offizielle Konzept ist. Die Verwendung von „ungebunden“ zur Beschreibung lautet: Global bindet den Variablennamen der obersten Ebene an den lokalen Variablennamen und ändert sich gleichzeitig. Wenn Python a = 1 erkennt, erkennt es, dass a vorhanden ist lokal, wenn also „auf ein Objekt zeigt“ (da alle Python-Variablen Referenzen sind), war der Aufruf von „a“ zuvor ein unzulässiges Verhalten, aber dieses Verhalten unterscheidet sich von „NameError“ und ist als ungebundenes lokales Verhalten definiert.
2.
Verwenden Sie variable Variablen wie list, dict
In [127]: def x(): .....: l = ["in msg"] .....: def y(): .....: msg = l[0] .....: print "msg =",msg .....: l[:] = ["out msg"] .....: y() .....: print l[0] .....: In [128]: x() msg = in msg out msg
Keine Fehler, perfekt!
Achten Sie auf die Anweisung l[:] = ["out msg"] und verwenden Sie die Slice-Zuweisung, andernfalls
In [129]: def x(): l = ["in msg"] def y(): msg = l[0] print "msg =",msg l = ["out msg"] y() print l[0] .....: In [130]: x() --------------------------------------------------------------------------- UnboundLocalError Traceback (most recent call last) <ipython-input-130-7354d77c61ac> in <module>() ----> 1 x() <ipython-input-129-d44e750e285f> in x() 5 print "msg =",msg 6 l = ["out msg"] ----> 7 y() 8 print l[0] 9 <ipython-input-129-d44e750e285f> in y() 2 l = ["in msg"] 3 def y(): ----> 4 msg = l[0] 5 print "msg =",msg 6 l = ["out msg"] UnboundLocalError: local variable 'l' referenced before assignment
Ein UnboundLocalError tritt erneut auf, da die sechste Codezeile l eine neue Liste zuweist.
3.
Verwenden Sie die Parameterübergabe.
In [136]: def x(): .....: a, b = 1, 2 .....: def y(a = a, b = b): .....: a, b = 3, 4 .....: return a, b .....: a, b = y() .....: print a, b .....: In [137]: x() 3 4
Achten Sie darauf, keine variablen Objekte wie Listen auf Standardparameter zu setzen.
Das Obige ist eine Reihe von Problemen, die durch die Verwendung von GLOBAL in PYTHON verursacht wurden. Ich hoffe, es wird Ihnen hilfreich sein. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Herausgeber wird Ihnen antworten rechtzeitig. Ich möchte mich auch bei allen für Ihre Unterstützung der Script House-Website bedanken!