meinst. Wie soll ich die Datei schließen?Das die Dateien nicht wieder geschlossen werden würde ich als Programmfehler ansehen. Man verlässt sich da auf Implementierungsdetails und Dateihandles sind eine limitierte Systemressource.
Aufgabenverwaltung
Arbeite gerade an weiteren Verbesserungen, nur leider verstehe ich nicht, was du mit
@Xfd7887a: Dateiobjekte haben eine `close()`-Methode dafür. Oder man verwendet das `open()` zusammen mit der ``with``-Anweisung.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
So:Xfd7887a hat geschrieben:Wie soll ich die Datei schließen?
Code: Alles auswählen
# Nutze die ``close``-methode auf File-Objekten:
file_object.close()
Code: Alles auswählen
with open(...) as file_object:
# hantiere hier mit dem Objekt, rufe *nicht* ``close`` auf!
# das passiert nach Verlassen des Blocks automatisch :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Ok, danke. Wenn ich nun aber versuche, die Datei zu schließen, kommt folgende Meldung:
Das ist sicherlich logisch, da ich den Inhalt der Datei unter der Variablen "AUFGABEN" gespeichert habe.
Wie komme ich jetzt an die eigentliche Datei ran?
Code: Alles auswählen
AttributeError: 'dict' object has no attribute 'close'.
Wie komme ich jetzt an die eigentliche Datei ran?
@Xfd7887a: Du musst diese Methode auf dem *Dateiobjekt* aufrufen, und nicht auf dem Wörterbuch mit den Aufgaben. Dazu musst Du dieses Dateiobjekt an einen Namen binden. Besser wäre aber das mit der ``with``-Anweisung zu machen.
Habe das ganze so geändert:
Wird nun die Datei automatisch geschlossen?
Code: Alles auswählen
try:
with open("aufgaben.txt") as aufgaben_datei:
AUFGABEN = load(aufgaben_datei)
except:
with open("aufgaben.txt", "w") as aufgaben_datei:
dump(dict(), aufgaben_datei)
AUFGABEN = load(aufgaben_datei)
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Das ist eine komische Logik... ich musste da erst genau hinsehen, um zu begreifen, dass Du die Datei "leer" anlegst, wenn diese nicht geöffnet werden konnte.
Lesen und Schreiben würde ich komplett trennen, also eine Funktion ``dump`` und eine ``load`` oder so ähnlich.
Wenn Die Datei (noch) nicht existiert, dann gib einfach ein *leeres* Dictionary zurück
Das ist imho das sinnvollere Vorgehen!
Und fange niemals *alle* Exceptions ab, sondern nur die, auf die Du reagieren willst. In Deinem Falle also eine ``FileNotFoundError``-Exception.
Ansonsten: Ja, so werden die Dateien automatisch geschlossen.
Lesen und Schreiben würde ich komplett trennen, also eine Funktion ``dump`` und eine ``load`` oder so ähnlich.
Wenn Die Datei (noch) nicht existiert, dann gib einfach ein *leeres* Dictionary zurück
Das ist imho das sinnvollere Vorgehen!
Und fange niemals *alle* Exceptions ab, sondern nur die, auf die Du reagieren willst. In Deinem Falle also eine ``FileNotFoundError``-Exception.
Ansonsten: Ja, so werden die Dateien automatisch geschlossen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Genau das. Spiel mal durch was passiert, wenn du keine Spreibrechte fuer die Datei "aufgaben.txt" hastHyperion hat geschrieben:Und fange niemals *alle* Exceptions ab, sondern nur die, auf die Du reagieren willst. In Deinem Falle also eine ``FileNotFoundError``-Exception.
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Ich habe gerade versucht mein Programm zu "verbessern". Leider habe ich rumgemurkst, jetzt werden Änderungen einfach nicht gespeichert. Hier das Script: https://github.com/toxinman/stuff/blob/master/todo.py Ich weiß nicht, was ich geändert habe.
Ich gebe mal einen Tipp ab: Du beendest das Programm über die "programm_beenden"-Funktion. Diese ruft dann allerdings die exit-Funktion auf, welche das Programm direkt beendet. Dadurch wird das Speichern nicht mehr ausgeführt. Bei solchen Problemen hilft es oft, wenn du ein paar print-Statements in dein Programm einbaust. Dann siehst du recht schnell ob du irgendwo im Code ankommst oder nicht.
Das Leben ist wie ein Tennisball.
- pillmuncher
- User
- Beiträge: 1484
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
Muss es nicht Speibrechte[*] heißen?cofi hat geschrieben:[...] keine Spreibrechte fuer die Datei [...]
[*]Von Bairisch: speiben (schbaim): spucken, erbrechen.
In specifications, Murphy's Law supersedes Ohm's.
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
@pillmuncher: Dann ist immer noch ein "b" zu viel
Nein, das ist ein reichlich verungluecktes "Schreibrechte"
Nein, das ist ein reichlich verungluecktes "Schreibrechte"
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
@Xfd7887a: Wie stellst Du das denn fest? Hast Du nach Programmende tatsächlich mal in die Datei geschaut, oder denkst Du das nur weil nach einem erneuten Programmstart keine Daten in `AUFGABEN` sind?
Hier sieht man schön warum nackte ``except``\s ohne konkrete Ausnahmen keine gute Idee sind. Du rennst wegen einem Programmierfehler immer in das ``except`` in Zeile 103 und merkst das nicht, weil dort eben nicht nur die Ausnahmensituationen behandelt werden die Du erwartest, sondern auch mindestens eine die bei einem korrekten Programm gar nicht vorkommen dürfte. Und der Fehler sorgt auch dafür das die Datei bei jedem Programmstart geleert wird.
Die Schreibweise von `AUFGABEN` ist für eine Datenstruktur die während des Programmlaufs verändert werden soll übrigens falsch. Ausschliesslich Grossbuchstaben werden per Konvention nur für konstante Werte verwendet.
Es wäre übrigens praktischer wenn Du beim Verlinken Deines Quelltextes nicht immer wieder das Master-Tag verwenden würdest, sondern einen Link auf die konkrete Revision die gemeint ist. Denn sonst kann man nach Änderungen an Master die Antworten hier nicht mehr wirklich nachvollziehen, sondern muss sich erst anhand des Beitragsdatums die richtige Revision auf Github heraus suchen.
Hier sieht man schön warum nackte ``except``\s ohne konkrete Ausnahmen keine gute Idee sind. Du rennst wegen einem Programmierfehler immer in das ``except`` in Zeile 103 und merkst das nicht, weil dort eben nicht nur die Ausnahmensituationen behandelt werden die Du erwartest, sondern auch mindestens eine die bei einem korrekten Programm gar nicht vorkommen dürfte. Und der Fehler sorgt auch dafür das die Datei bei jedem Programmstart geleert wird.
Die Schreibweise von `AUFGABEN` ist für eine Datenstruktur die während des Programmlaufs verändert werden soll übrigens falsch. Ausschliesslich Grossbuchstaben werden per Konvention nur für konstante Werte verwendet.
Es wäre übrigens praktischer wenn Du beim Verlinken Deines Quelltextes nicht immer wieder das Master-Tag verwenden würdest, sondern einen Link auf die konkrete Revision die gemeint ist. Denn sonst kann man nach Änderungen an Master die Antworten hier nicht mehr wirklich nachvollziehen, sondern muss sich erst anhand des Beitragsdatums die richtige Revision auf Github heraus suchen.
Ich glaube, ich habe nicht verstanden, was du meinst. Meine Änderung:
Leider funktioniert es immer noch nicht, obwohl ich doch eigentlich nur abfange, wenn die Datei leer ist.
Code: Alles auswählen
with open("aufgaben.txt", "w") as aufgaben_datei:
try:
- AUFGABEN = load(aufgaben_datei)
- except:
- AUFGABEN = dict()
+ aufgaben = load(aufgaben_datei)
+ except IOError:
+ aufgaben = dict()
Welcher Fehler ist das?Hier sieht man schön warum nackte ``except``\s ohne konkrete Ausnahmen keine gute Idee sind. Du rennst wegen einem Programmierfehler immer in das ``except``
Wie geht das?Es wäre übrigens praktischer wenn Du beim Verlinken Deines Quelltextes nicht immer wieder das Master-Tag verwenden würdest, sondern einen Link auf die konkrete Revision die gemeint ist.
@Xfd7887a: Die Änderung behandelt jetzt alles was ein `IOError` ist, das ist mehr als nur das die Datei nicht existiert. Der Fall das die Datei nicht existiert, kann nebenbei gesagt innerhalb des ``try``/``except`` überhaupt gar nicht auftreten weil Du dort bereits ein geöffnetes Dateiobjekt vor dem betreten hast. Dann *muss* die Datei existieren, denn wie könnte man sonst so ein Objekt haben!?
Gib der Ausnahme in dem ``except`` noch einen Namen und gib das Ausnahmeobjekt dann doch einfach mal mit ``print`` aus, dann siehst Du ja was die Nachricht von dem Objekt sagt.
Zum verlinken: Du könntest zum Beispiel über die History gehen und da beim gewünschten Commit-Stand auf „Browse code →” klicken um zum Stand der Datei zu dem konkreten Commit zu kommen. So bin ich auf den Link in meinem letzten Beitrag gekommen.
Gib der Ausnahme in dem ``except`` noch einen Namen und gib das Ausnahmeobjekt dann doch einfach mal mit ``print`` aus, dann siehst Du ja was die Nachricht von dem Objekt sagt.
Zum verlinken: Du könntest zum Beispiel über die History gehen und da beim gewünschten Commit-Stand auf „Browse code →” klicken um zum Stand der Datei zu dem konkreten Commit zu kommen. So bin ich auf den Link in meinem letzten Beitrag gekommen.
Die Ausgabe ist: Das verstehe ich nicht, ich habe die Datei doch geöffnet.
Code: Alles auswählen
File not open for reading
Ja, die Datei ist immer da. Mir geht's im Moment darum, ob sie gefüllt oder leer ist.Der Fall das die Datei nicht existiert, kann nebenbei gesagt innerhalb des ``try``/``except`` überhaupt gar nicht auftreten weil Du dort bereits ein geöffnetes Dateiobjekt vor dem betreten hast.