Heim > Backend-Entwicklung > Python-Tutorial > Analyse von Variablenreferenzen in Python-Abschlüssen

Analyse von Variablenreferenzen in Python-Abschlüssen

巴扎黑
Freigeben: 2016-12-08 10:57:02
Original
1331 Leute haben es durchsucht

Der Titel sieht sehr Tiger aus, aber ich wage es tatsächlich nicht, ihn Analyse zu nennen. Ich habe in diesem Bereich noch einige Defizite. Früher war es vielleicht in Ordnung, aber jetzt habe ich nicht mehr so ​​viel Zeit und Energie, Sprachen zu lernen. Wenn mit der Erklärung etwas nicht stimmt, können Sie gerne nach Banzhuan kommen und die Öffentlichkeit nicht in die Irre führen.

Lassen Sie uns dieses Mal direkt über das Problem sprechen. Heute hat mir @neiddy (javaeye) von dem Schließungsproblem erzählt. Es ist interessant, diese wenigen Beispiele zu sehen, und ich möchte es verstehen.

Schauen Sie sich zwei Codeteile an:

>>> def foo():
       a = 1
       def bar():
              a = a +1
              return a
       return bar()
 
>>> foo()
Traceback (most recent call last):
  File "<pyshell#73>", line 1, in <module>
    foo()
  File "<pyshell#72>", line 6, in foo
    return bar()
  File "<pyshell#72>", line 4, in bar
    a = a +1
UnboundLocalError: local variable &#39;a&#39; referenced before assignment
Nach dem Login kopieren
>>> def foo():
       a = [1]
       def bar():
              a[0] = a[0] + 1
              return a[0]
       return bar()
 
>>> foo()2
Nach dem Login kopieren

Es ist immer noch ein gutes Gefühl, funktionale Programmierung durch Abschlüsse zu erleben. Unter dem Originaltext stehen keine Klammern, sonst wäre die Return-Funktion selbst bedeutungslos. Lassen Sie uns über dieses magische Phänomen sprechen. Der Artikel sagt nur, dass es in Ordnung ist, wenn es in einen Container umgewandelt wird.

Ich habe einige Dinge über Speicherverwaltung und Speicherzuweisung gegoogelt, konnte aber keinen Ausweg finden, als mich an den Quellcode zu wenden. Ich habe es noch nie gesehen und es ist zu ineffizient, es direkt zu lesen. Glücklicherweise hat jemand es zusammengefasst und empfiehlt „Ausführliche Python-Programmierung“ von „Yuhen Q.yuhen“.

Die Codeanalyse des direkten Verschlussteils wird im Abschnitt über Schließungen erwähnt, es gibt jedoch keinen Mechanismus, um speziell auf dieses seltsame Problem einzugehen.

Lesen Sie das Buch noch einmal und beziehen Sie sich auf die Abschnitte „Parameter“ und „Abschluss“ im Buch, basierend auf seiner Erklärung und dem beigefügten Quellcode.

Yu Chen erwähnte am Ende des Kapitels: „Das Prinzip der Implementierung des Abschlusses durch CPython ist nicht kompliziert. Um es ganz klar auszudrücken: Es besteht darin, das referenzierte äußere Objekt an das innere Funktionsobjekt anzuhängen, das jedes Mal neu erstellt wird ( func_closure ). „

Dieser Satz ist eine Zusammenfassung des vorherigen Satzes und enthält auch wichtige Informationen, d In den Speicher wird auf den Stapel des Objekts zugegriffen und als Wert im C-Sprachcode übergeben.

Zum Beispiel bezieht sich a im ersten Code tatsächlich auf 1, und seine eigenen co_nlocals sind 1, das heißt, eine lokale Variable ist das a vor dem Gleichheitszeichen (das ist nicht ganz richtig, ich hoffe es nur hilft, diese Frage zu verstehen). Da es sich um eine lokale Variable a handelt, muss a = a +1 UnboundLocalError auslösen.

Was die zweite Frage betrifft: Obwohl die gleiche Situation besteht, ändert sich der spezifische Punkt, auf den jede Position im Array zeigt, nicht, selbst wenn er als Wert übergeben wird, und der Wert der angegebenen Position bleibt bestehen geändert werden, also wenn Es ist möglich, wenn es sich um ein Containerobjekt handelt.

Was ich an mir selbst hasse, ist, dass ich immer das Gefühl habe, es nicht klar erklären zu können. Tatsächlich ist es ein Zeigerspiel, das ich oft gespielt habe, als ich die Sprache C zum ersten Mal gelernt habe ist schrecklich, ich hoffe, es kann darauf hingewiesen werden. Es ist gefährlich. Der nächste Schritt ist sehr einfach, um einen Code zu überprüfen. Das heißt, wenn Sie diesen Wert nur ausgeben und keine lokalen Variablen festlegen, sollte er ausgeführt werden können.

>>> def foo():
       a = 1
       def bar():
              return a
       return bar()
 
>>> foo()
1
Nach dem Login kopieren

Die Dinge verliefen wie erwartet. Um es genauer zu erleben, schauen Sie sich den von Yuhen analysierten Code genau an. Das Verständnis der Mechanik ist ein langer Weg. Python wird immer interessanter. Das Schreiben von Code mit Python-Ideen hat viele Vorteile.

Übrigens, übrigens

>>> flist = []
>>> for i in range(3):
       def foo(x): print x + i
       flist.append(foo)
 
>>> for f in flist:
       f(2)
 
4
4
4
Nach dem Login kopieren

In dem Artikel wurde erwähnt, dass dieser Code dadurch verursacht wird, dass ich nicht zerstört wurde. Ich habe dieses Ding heute auch gesehen, als ich nach Speicherzuordnung gesucht habe. Beim Programmieren sollten Sie versuchen, das Listenverständnis zu nutzen, um „for“ und „while“ zu reduzieren. Einerseits ist die funktionale Programmierung prägnant und klar, andererseits verbessert sie die Leistung und spart einen Zähler.

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage