with open(file) vs. open(file)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
de_tom
User
Beiträge: 15
Registriert: Dienstag 19. Juli 2016, 19:34

Warum erhalte ich beim Öffnen einer Textdatei mit with open(filename) ein anderes Ergebnis als mit open(filename)?

Hier zwei Codes, die eigentlich das Gleiche tun sollten:

1. Mit with open(filename):

Code: Alles auswählen

import sys

def read_file(filename):
	with open(filename) as f:
		data = f.read()
		return data

def main():
	file_content = read_file(sys.argv[1])
	for zeile in file_content:
		print(zeile)

if __name__ == '__main__':
	main()
2. Mit open(filename):

Code: Alles auswählen

import sys

def read_file(filename):
	data = open(filename)
	return data

def main():
	file_content = read_file(sys.argv[1])
	for zeile in file_content:
		print(zeile)

if __name__ == '__main__':
	main()
Eingelesen habe ich folgende (frei erfundene) Textdatei:

Code: Alles auswählen

Hans;Huber;Stuttgart;198-8852364780
Fred;Maier;Passau;198-8776522227
Silke;Schulz;Fellbach;100-5544274889
Thomas;Braun;Kirchheim;198-7622900811
Josef;Kroll;Traunstein;198-1220009836
Kristina;Krauss;Hochberg;100-8192377652
Sara;Vogt;Vellberg;100-9225367888
Thorsten;Klenk;Offenburg;198-0119928736
Selina;Neumann;Waiblingen;100-8772200195

Beim 1. Code wird jedes einzelne Zeichen der Datei zeilenweise ausgegeben.
Beim 2. Code werden die Zeilen der Datei zeilenweise ausgegeben (so wie ich es eigentlich will).

Liegt es daran, dass with open() eine Objekt der Klasse 'str' zurückgibt und open(filename) eine Objekt der Klasse '_io.TextIOWrapper'?
Kann ich eine Textdatei mit with open() (was ich lieber verwenden würde) nur in einer Schleife zeilenweise auslesen?

Gruß,
Tom
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@de_tom: Du machst auch zwei völlig verschiedene Dinge. Im ersten Fall liest Du tatsächlich die ganze Datei in einen String und im zweiten Fall ist der Funktionsname falsch, weil Da nur ein Dateiobjekt erzeugt wird.

Die Funktion sollte vielleicht so aussehen:

Code: Alles auswählen

def read_file(filename):
    with open(filename) as f:
       return list(f)
Besser gleich auch noch das csv-Modul verwenden.

Ach ja, eingerückt wird immer mit 4 Leerzeichen pro Ebene.
de_tom
User
Beiträge: 15
Registriert: Dienstag 19. Juli 2016, 19:34

OK. Das habe ich soweit verstanden. Vielen Dank.
In Deiner Funktion speicherst Du den Inhalt des erzeugten Dateiobjekts (f) in einer Liste ab. Ist diese Aussage so korrekt?
Und: Ist es bei Textdateien also so, dass eine gesamte Zeile quasi immer als 1 "Element" betrachtet wird?

Gruß
Tom
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

In #1 benutzt du .read() und in #2 nicht.

Ob du with benutzt hat hier keine Auswirkung.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@de_tom: Dateiobjekte kann man auf verschiedene Arten benutzen. Bei Textdateien hat man einen Strom an Daten, den man entweder zeichenweise oder zeilenweise abgreifen kann. `read` -> zeichenweise, `readline` -> zeilenweise.

Jetzt können sich Objekte wie Iteratoren verhalten, also z.B. in einer for-Schleife oder im list-Aufruf Elemente liefern. Dateiobjekte rufen, als Iterator angesprochen, intern dann die Funktion readline auf.
de_tom
User
Beiträge: 15
Registriert: Dienstag 19. Juli 2016, 19:34

Vielen Dank euch beiden,

das hat mir für's Verständnis sehr viel geholfen.

Danke!
Antworten