Warum ist eine Klassenvariable nicht im Listenverständnis definiert, sondern eine andere ist?

Ich lese gerade die Antwort auf diese Frage: Zugriff auf Klassenvariablen aus einem Listenverständnis in der Klassendefinition

Es hilft mir zu verstehen, warum der folgende Code zu NameError: name 'x' is not defined :

 class A: x = 1 data = [0, 1, 2, 3] new_data = [i + x for i in data] print(new_data) 

Der NameError tritt auf, weil x im speziellen Bereich für das Listenverständnis nicht definiert ist. Aber ich kann nicht verstehen, warum der folgende Code ohne Fehler funktioniert.

 class A: x = 1 data = [0, 1, 2, 3] new_data = [i for i in data] print(new_data) 

Ich bekomme die Ausgabe [0, 1, 2, 3] . Aber ich habe diesen Fehler erwartet: NameError: name 'data' is not defined weil ich genau wie im vorherigen Beispiel erwartete, dass der Name x nicht im Bereich des Listenverstehens definiert ist. Ebenso wurden die NameError: name 'data' is not defined auch nicht in der Liste des Verständnisses.

Könnten Sie mir bitte helfen zu verstehen, warum x nicht im Bereich des Listenverständnisses definiert ist, aber data sind?

One Solution collect form web for “Warum ist eine Klassenvariable nicht im Listenverständnis definiert, sondern eine andere ist?”

data sind die Quelle des Listenverständnisses; Es ist der einzige Parameter, der an den verschachtelten Bereich übergeben wird.

Alles in der Liste Verständnis wird in einem separaten Bereich (als Funktion, im Grunde) ausgeführt, mit Ausnahme der iterable für die links am meisten for Schleife verwendet. Sie sehen dies im Bytecode:

 >>> def foo(): ... return [i for i in data] ... >>> dis.dis(foo) 2 0 LOAD_CONST 1 (<code object <listcomp> at 0x105390390, file "<stdin>", line 2>) 3 LOAD_CONST 2 ('foo.<locals>.<listcomp>') 6 MAKE_FUNCTION 0 9 LOAD_GLOBAL 0 (data) 12 GET_ITER 13 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 16 RETURN_VALUE 

Das <listcomp> wird wie eine Funktion aufgerufen und iter(data) als Argument übergeben ( CALL_FUNCTION wird mit 1 Positionsargument, dem GET_ITER Ergebnis) ausgeführt.

Das <listcomp> sucht nach einem Argument:

 >>> dis.dis(foo.__code__.co_consts[1]) 2 0 BUILD_LIST 0 3 LOAD_FAST 0 (.0) >> 6 FOR_ITER 12 (to 21) 9 STORE_FAST 1 (i) 12 LOAD_FAST 1 (i) 15 LIST_APPEND 2 18 JUMP_ABSOLUTE 6 >> 21 RETURN_VALUE 

Der LOAD_FAST Aufruf bezieht sich auf das erste und einzige Positions-Argument, das LOAD_FAST . Es ist hier unbenannt, weil es nie eine Funktionsdefinition gab, um ihm einen Namen zu geben.

Alle zusätzlichen Namen, die im Listenverstehen verwendet werden (oder gesetzt oder dict Verständnis oder Generatorausdruck für diese Angelegenheit) sind entweder Einheimische, Schließungen oder globals, nicht Parameter.

  • Pythonumfang [doppelte]
  • Python: Variablen sind noch zugänglich, wenn in try oder if definiert?
  • Scoping in Python 'für' Schleifen
  • Mit einer Variablen in einem Versuch, Fang, endgültige Aussage, ohne es draußen zu erklären
  • Wie man globale Variablen unter verschiedenen Modulen in Python hat
  • Python - Wie man eine globale Variable aus einer Funktion
  • Globals und Einheimische in python exec ()
  • Python Variable Scope (Vorbehalt durch Verweis oder Kopie?)
  • Den Block der Befehle, die in der mit Anweisung ausgeführt werden sollen
  • Warum können Funktionen in Python-Druckvariablen im Umschließungsbereich funktionieren, können sie aber nicht in der Zuordnung verwenden?
  • Lambda-Funktion acessing außerhalb variabel [duplicate]
  • Python ist die beste Programmiersprache der Welt.