Ja, file
ist eine Variable, die auf den von open()
zurückgegebenen Kontextmanager verweist. Es ist zufällig das gleiche Objekt. Mit anderen Worten, file
verweist auf ein Dateiobjekt.
Sie auch dies hätte tun können, um den gleichen Effekt hier:
file = open(filename, "a")
try:
file.write("Hello world")
finally:
file.close()
so dass die Datei automatisch geschlossen wird. Das liegt daran, dass Dateiobjekte Kontextmanager sind; sie unterstützen die context manager protocol. Technisch gesehen ist die with context_manager as <name>
Zielvariable an den Rückgabewert context_manager.__enter__()
gebunden, aber ein Dateiobjekt gibt sich von dieser Methode zurück und die Methode file.__exit__()
schließt die Datei. Siehe with
compound statement documentation.
Wenn Sie nun Druck ein Objekt, das nicht eine String-Darstellung hat, wird es die repr()
Funktion Druck:
>>> repr(open('/dev/null'))
"<_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'>"
>>> print(repr(open('/dev/null')))
<_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'>
so ja, das ist nur eine andere Aufgabe, eine mit einem benutzerdefinierte, hilfreiche Darstellung. Datei-Objekte implementieren die object.__repr__()
hook dies zu produzieren:
>>> open('/dev/null').__repr__()
"<_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'>"
Der Name des Dateiobjekts kann auch verwirrend hier werden. Das liegt daran, dass Dateiobjekte in Python Teil einer Reihe von Objekten sind, die durch die io
module definiert sind; ein TextIOWrapper
object wickelt eine Puffer (hier ein BufferedReader
, was wiederum die rohe, binäre Dateiobjekt in Form eines FileIO
object wickeln:
>>> devnull = open('/dev/null', 'r')
>>> devnull
<_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'>
>>> devnull.buffer
<_io.BufferedReader name='/dev/null'>
>>> devnull.buffer.raw
<_io.FileIO name='/dev/null' mode='rb' closefd=True>
Das ist alles nur Tech-Detail, das Sie brauchen nicht normal Sorgen zu machen. führt Jedes Objekt eine bestimmte Funktion, und jemand, um erweiterte E/A-Gerangel tun können, diese mischen.
Es * ist * eine Variable und speichert ein 'TextIOWrapper' Objekt. Wie ist das "nichts"? – deceze
Warum sieht es nicht wie eine Variable aus? Warum speichert es nichts? Warum denkst du, dass es keine Variable ist? Es ist unklar von deiner Frage, wo die Verwirrung liegt. –
Die Dokumentation ist [hier] (https://docs.python.org/3/reference/compound_stmts.html#with) frei verfügbar. – vaultah