Re: [Python-de] Frage zum configparser
Am Wed, 18 Jan 2017 22:45:26 +0100 schrieb Arnold Krille:
On Wed, 18 Jan 2017 17:21:53 +0000 (UTC) Manfred Gil <manfred-gil@t-online.de> wrote:
kleine Frage zum configparser,
<code> conpar = configparser.ConfigParser()
conpar.read('config.ini')
# Einlesen der Daten
</code>
muß ich die Datei "config.ini" nicht irgendwie wieder schließen? in der Doku habe ich nix dazu gefunden. Oder geschieht diese nach dem Einlesen automatisch durch den configparser?
Die anderen haben schon die vernünftige Antwort gegeben. Ich möchte gerne noch sagen, warum mich dir Frage überrascht hat ;-)
Der code oben zeigt für mich recht eindeutig, das lediglich der Name der Datei übergeben wird. Du musst Dich selber nicht kümmern: * ob die Datei existiert und was passiert wenn nicht, * ob die Datei lesbar ist, * ob die Datei richtig formatiert ist, * ob die Datei zum lesen, schreiben, anfügen, im Textmodus oder im Binärmodus, mit CR+LF oder mit LF geöffnet und gelesen werden muss.
Warum (zum Geier ;-) ) kommst du da noch auf die Idee, das Du Dich um das Schließen selber kümmern müsstest? Wäre das dann nicht eine _sehr_ schlecht designte API? Und müsste dann nicht "conpar.read(…)" das file-objekt oder den file-handle zurück geben? Erwartest Du dann nicht, das dann in der Dokumentation steht "Achja, kümmer Dich bitte selber darum das ding zu schließen"?
Vielleicht gibt es APIs, die sowas tatsächlich mit Dir als ihrem Nutzer machen. Aber wenn es sich um die Standardbibliotheke handelt dürfen wir schon besseres erwarten ;-)
Hallo Arnold, kann es sein, das Du gestern einen schlechten Tag hattest ;-) Wieso sollte ich mir _nicht_ Gedanken darum machen, ob ich das File wieder schließen sollte. <code> daten = open('READNE.txt','r') text = daten.read() daten.close() print(text) </code> ist für mich im ersten Augenblick nichts anderes. Sicher, jetzt kommen alle Python Nerds an und erklären mir den Unterschied, zwischen den beiden code stücken von mir. Ich bin und nicht anderes behaupte ich von mir, ein Hobby Python(man). in meiner "kleinen" Freizeit ... nach dem Job ... und Familie, "Bastle" ich mir Programme die mir genügen sollten. Sicher sind meine Ansprüche an mir selber, meist zu hoch angesetzt, doch ich beiss mich durch. Manche Probleme lösen sich durchs lesen von Dokus oder durch das Mitlesen in Forum. Andere Sachen sind dann irgendwie nicht ganz geheuer für mich, wie mit dem Configpraser. Aber na ja, lassen wir das. Hier hatte ich schnelle und unkomplizierte Hilfe bekommen, wie meistens... ne immer :-)
Happy Coding,
Arnold
Wünsche ich Dir auch. Gruß Manfred --
Hallo Manfred, tl;dr: Entschuldigung. On Thu, 19 Jan 2017 17:53:29 +0000 (UTC) Manfred Gil <manfred-gil@t-online.de> wrote:
kann es sein, das Du gestern einen schlechten Tag hattest ;-)
Ja, vielleicht. Entschuldigung falls das Emotionen in mein Email gepackt hat, die bei Dir zu negativen Emotionen geführt haben. Das wollte ich nicht!
Wieso sollte ich mir _nicht_ Gedanken darum machen, ob ich das File wieder schließen sollte. <code> daten = open('READNE.txt','r') text = daten.read() daten.close() print(text)
</code>
ist für mich im ersten Augenblick nichts anderes. Sicher, jetzt kommen alle Python Nerds an und erklären mir den Unterschied, zwischen den beiden code stücken von mir.
Yep, hier kommt einer. Denn: Wenn ich Deine ursprüngliche Frage richtig verstehe, dann ist das Beispiel oben nicht passend zu Deiner ursprünglichen Frage. Das Beispiel müsste lauten: <code> text = read_from_file('READNE.txt') print(text) </code> Und wenn ich Dich richtig verstehen, denkst Du darüber nach, ob Du das file schliessen musst? Meine Gegenfrage lautet: Welches File? Die Implementierung von read_from_file ist nicht bekannt, die Eingabe in die Funktion ist ein Dateiname (und Pfad) als string, die Rückgabe der Funktion ist auch ein string mit dem Inhalt der Datei. Wenn Du in Python Dateien selber öffnen willst, dann werden die repräsentiert durch File-Objekte (high level) oder durch file-handles (low level). So ein File-Objekt erhälst Du, wenn Du 'open("filename", "r")' machst. Ein file-handle ist im Prinzip ein integer, der die geöffnete Datei im Speicher markiert und wird Dir von 'os.open("filename", …)' zurück gegeben. Das File-Objekt lässt sich schliessen indem man auf dem Objekt '.close()' aufruft, der file-handle wird geschlossen durch 'os.close(handle)'. Aber: In dem Beispiel hast Du beides nicht und bekommst auch nichts davon aus der Funktion zurück. Und weder auf dem string des Dateinamens, noch auf dem string des Rückgabewertes kann man irgendwas schließen. ('text.close()' gibt nen AttributeError.) Jetzt zur Implementierung von 'read_from_file': Es gibt mehrere Möglichkeiten den Inhalt einer Datei zu lesen, ein paar davon will ich im folgenden Aufschreiben. <code> def read_from_file1(filename): f = open(filename, 'r') text = f.read() f.close() return f def read_from_file2(filename): with open(filename, 'r') as f: text = f.read() return f def read_from_file3(filename): f = open(filename, 'r') return f.read() def read_from_file4(filename): return open(filename, 'r').read() def read_from_file5(filename): f = os.open(filename, os.O_RDONLY|os.O_TEXT) text = os.read(f, INT_MAX) # read, a lot os.close(f) return text </code> Alle diese Funktionen machen das gleiche, sie öffnen die Datei, lesen den Inhalt (in Fall 5 nur maximal die ersten INT_MAX bytes ;) ) und schliessen die Datei wieder um den gelesen Text dann zurück zu geben. Lediglich im Fall 5 ist es möglich das der file-handle offen zurück bleibt und dann nicht mehr erreichbar ist, vorausgesetzt man vergisst die Zeile mit 'os.close(f)'. Fun Fact: Wenn das File-Objekt gelöscht wird, schließt es die Datei wenn nötig. Und gelöscht wird das Objekt entweder weil es mit 'del' gelöscht wird, oder weil es out-of-scope geht. Beispielsweise weil die Funktion, in der es lebt, zu Ende ist (Fall 3 und 4). Der Kontextmanager in Fall 4 sorgt übrigens dafür, das die Datei geschlossen wird egal was für Fehler innerhalb des Blocks passieren.
Ich bin und nicht anderes behaupte ich von mir, ein Hobby Python(man). in meiner "kleinen" Freizeit ... nach dem Job ... und Familie, "Bastle" ich mir Programme die mir genügen sollten. Sicher sind meine Ansprüche an mir selber, meist zu hoch angesetzt, doch ich beiss mich durch. Manche Probleme lösen sich durchs lesen von Dokus oder durch das Mitlesen in Forum. Andere Sachen sind dann irgendwie nicht ganz geheuer für mich, wie mit dem Configpraser.
Tut mir leid wenn ich da gestern (und heute?) etwas Oberlehrerhaft rüber komme. Das will ich gar nicht. Oder meine es zumindest doch nur gut. Beim Anblick Deiner Frage hatte ich halt zwei Befürchtungen (siehe Svens Vermutung): Entweder hast Du in Deiner C- und Perl-Erfahrung tatsächlich schon so viele Fälle von so einem Konstrukt gesehen, das Du Dir Deine Originalfrage da tatsächlich sehr häufig so stellen musst. Dann sinken C und Perl in meinem ansehen noch tiefer und ich werde nie wieder eine Zeile davon lesen, geschweige denn schreiben. Oder Du weißt es einfach noch nicht besser. Was nicht schlimm ist. Wir haben schließlich alle mal angefangen. Dann ist meine Hoffnung, das Du irgendwann (möglichst bald!) soweit bist, das Du Code nicht nur "für Dich" sondern auch "für Alle" schreibst. Und dann möchte ich Dir helfen, das es guter Code ist mit klaren Konzepten und eindeutigen Schnittstellen. Nicht das ich dann irgendwann über Code stolpere, der eine globale Variable nutzt um ein file-Objekt offen zu lassen damit ich es selber schließen muss. Oder so…
Aber na ja, lassen wir das. Hier hatte ich schnelle und unkomplizierte Hilfe bekommen, wie meistens... ne immer :-)
Hm, vielleicht will man nicht nur schnelle Hilfe sondern manchmal auch noch ein wenig über Code und Konzepte philosophieren? Programmieren bzw. Software entwickeln hat meiner Erfahrung immer weniger mit Code und immer mehr mit Nachdenken zu tun je mehr Entwicklungserfahrung man hat. Bis denn, Arnold
participants (2)
-
Arnold Krille
-
Manfred Gil