2017-06-08 3 views
2

In einem Python-Skript außerhalb verwenden, stieß ich auf eine Variable, die in einer with Anweisung definiert wurden, aber das war außerhalb der Aussage, wie file im folgende Beispiel verwendet:Python Variable mit Anweisung

with open(fname, 'r') as file: 
    pass 
print(file.mode) 

Intuitiv I würde sagen, dass file nicht außerhalb der with Erklärung existieren sollte und dass dies nur zufällig funktioniert. Ich konnte in der Python-Dokumentation keine schlüssige Aussage darüber finden, ob das funktionieren sollte oder nicht. Ist diese Art von Anweisung sicher für die Verwendung (auch für zukünftige Python-Versionen) oder sollte sie vermieden werden? Ein Zeiger auf diese Information in den Python-Dokumenten wäre ebenfalls sehr hilfreich.

+1

Der Code Sie auf dem Laufenden sollte nicht funktionieren. Wenn Sie den Kontextmanager (den with-Block) verlassen, wird die Datei geschlossen. **Ich stehe korrigiert. Siehe Kommentare unten. ** –

+0

@WillDaSilva haben Sie es versucht? Es funktioniert für mich in Python 2.7 – asongtoruin

+3

Es funktioniert, da 'file.mode' greift nicht auf die Datei selbst, nur das Python-Objekt. – Octaviour

Antwort

1

Der variable Bereich gilt nur für die Ebenen function, module und class. Wenn Sie sich in derselben Funktion/demselben Modul/derselben Klasse befinden, sind alle definierten Variablen innerhalb dieser Funktion/dieses Moduls/dieser Klasse verfügbar, unabhängig davon, ob sie in einem with, for, if usw. Block definiert wurde.

Zum Beispiel dieses:

for x in range(1): 
    y = 1 
print(y) 

genauso gültig (obwohl sinnlos), wie Ihr Beispiel ist die with Anweisung.

Allerdings müssen Sie vorsichtig sein, da die Variable im Code-Block definiert ist vielleicht nicht wirklich definiert werden, wenn der Block nicht eingegeben wird, wie in diesem Fall:

try: 
    with open('filedoesnotexist', 'r') as file: 
     pass 
except: 
    pass # just to emphasize point 

print(file.mode) 

Traceback (most recent call last): 
    File "<pyshell#43>", line 1, in <module> 
    file.mode 
NameError: name 'file' is not defined 

Good description of LEGB rule of thumb for variable scope