Was ist der Umfang einer Variablen, die in einer if-Anweisung initialisiert wurde?

266

Ich bin neu in Python, daher ist dies wahrscheinlich eine einfache Frage. Der folgende Code in einer Python-Datei (Modul) verwirrt mich leicht:

if __name__ == '__main__':
    x = 1

print x

In anderen Sprachen, in denen ich gearbeitet habe, würde dieser Code eine Ausnahme auslösen, da die xVariable lokal für die ifAnweisung ist und nicht außerhalb der Anweisung existieren sollte. Aber dieser Code wird ausgeführt und gedruckt 1. Kann jemand dieses Verhalten erklären? Sind alle in einem Modul erstellten Variablen global / für das gesamte Modul verfügbar?

froadie
quelle
17
Eine weitere Besonderheit, die Sie möglicherweise nicht kennen: Wenn die ifobige Anweisung nicht zutrifft (dh __name__beispielsweise nicht '__main__' , wenn Sie das Modul importieren, anstatt es auf oberster Ebene auszuführen), wurde xes nie gebunden, und die nachfolgende print xAnweisung wird ein werfen NameError: name 'x' is not defined.
Santa

Antworten:

301

Python-Variablen sind auf die innerste Funktion, Klasse oder das innerste Modul beschränkt, in dem sie zugewiesen sind. Steuerblöcke wie ifund whileBlöcke zählen nicht, daher wird eine Variable in einem zugewiesenifSteuerblöcke weiterhin einer Funktion, Klasse oder einem Modul zugeordnet ist.

(Implizite Funktionen, die durch einen Generatorausdruck oder ein Listen- / Satz- / Diktatverständnis definiert werden , zählen ebenso wie Lambda-Ausdrücke. Sie können keine Zuweisungsanweisung in eine dieser Funktionen einfügen, aber Lambda-Parameter und forKlauselziele sind implizite Zuweisungen.)

Luke Maurer
quelle
1
@ chandr3sh docs.python.org/3/tutorial/…
Fakher Mokadem
105

Ja, sie befinden sich im selben "lokalen Bereich", und tatsächlich ist Code wie dieser in Python üblich:

if condition:
  x = 'something'
else:
  x = 'something else'

use(x)

Beachten Sie, dass dies xnicht vor der Bedingung deklariert oder initialisiert wird, wie dies beispielsweise in C oder Java der Fall wäre.

Mit anderen Worten, Python verfügt nicht über Bereiche auf Blockebene. Seien Sie jedoch vorsichtig mit Beispielen wie

if False:
    x = 3
print(x)

das würde eindeutig eine NameErrorAusnahme auslösen.

Eli Bendersky
quelle
42

Der Umfang in Python folgt dieser Reihenfolge:

  • Suchen Sie den lokalen Bereich

  • Durchsuchen Sie den Umfang aller umschließenden Funktionen

  • Suchen Sie den globalen Bereich

  • Durchsuchen Sie die integrierten Funktionen

( Quelle )

Beachten Sie, dass ifund andere Schleifen- / Verzweigungskonstrukte nicht aufgelistet sind. Nur Klassen, Funktionen und Module bieten in Python einen ifGültigkeitsbereich. Daher hat alles, was in einem Block deklariert wird, denselben Gültigkeitsbereich wie alles, was außerhalb des Blocks deklariert wurde. Variablen werden beim Kompilieren nicht überprüft, weshalb andere Sprachen eine Ausnahme auslösen. In Python wird keine Ausnahme ausgelöst, solange die Variable zum gewünschten Zeitpunkt vorhanden ist.

Daniel G.
quelle
9

Wie Eli sagte, benötigt Python keine Variablendeklaration. In C würden Sie sagen:

int x;
if(something)
    x = 1;
else
    x = 2;

In Python ist die Deklaration jedoch implizit. Wenn Sie also x zuweisen, wird sie automatisch deklariert. Dies liegt daran, dass Python dynamisch typisiert ist - es würde in einer statisch typisierten Sprache nicht funktionieren, da abhängig vom verwendeten Pfad eine Variable möglicherweise verwendet wird, ohne deklariert zu werden. Dies würde zur Kompilierungszeit in einer statisch typisierten Sprache abgefangen werden, aber mit einer dynamisch typisierten Sprache ist dies zulässig.

Der einzige Grund, warum eine statisch typisierte Sprache ifaufgrund dieses Problems darauf beschränkt ist, Variablen außerhalb von Anweisungen in deklarieren zu müssen . Umfassen Sie die Dynamik!

Skilldrick
quelle
9

Im Gegensatz zu Sprachen wie C ist eine Python-Variable nicht nur im innersten "Block" für die gesamte Funktion (oder Klasse oder Modul) verfügbar, in der sie angezeigt wird. Es ist, als hättest du es erklärtint x oben in der Funktion (oder Klasse oder im Modul) deklariert, außer dass Sie in Python keine Variablen deklarieren müssen.

Beachten Sie, dass die Existenz der Variablen xnur zur Laufzeit überprüft wird, dh wenn Sie zur print xAnweisung gelangen. Wenn __name__nicht gleich, "__main__"dann würden Sie eine Ausnahme bekommen : NameError: name 'x' is not defined.

Paul Stephenson
quelle
Klassen erstellen keinen Bereich. Eine "lokale" Variable in einer Klasse wird beim Erstellen einfach zum Diktat der Klasse hinzugefügt.
Chepner
3

Ja. Dies gilt auch für den forUmfang. Funktioniert aber natürlich nicht.

In Ihrem Beispiel: Wenn die Bedingung in der ifAnweisung falsch ist, xwird sie jedoch nicht definiert.

Olivier Verdier
quelle
2

Sie führen diesen Code über die Befehlszeile aus, daher sind die ifBedingungen wahr und xfestgelegt. Vergleichen Sie:

>>> if False:
    y = 42


>>> y
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    y
NameError: name 'y' is not defined
SilentGhost
quelle
0

Und da Python-Typen nur zur Laufzeit überprüft werden, können Sie folgenden Code haben:

if True:
    x = 2
    y = 4
else:
    x = "One"
    y = "Two"
print(x + y)

Ich habe jedoch Probleme, mir andere Möglichkeiten auszudenken, wie der Code aufgrund von Typproblemen fehlerfrei funktionieren würde.

Cowang
quelle