Forum: PC-Programmierung file.close() Funktion - not defined


von Gargamel (Gast)


Lesenswert?

Hallo

In einem Python Script wird eine Datei geöffnet, Daten hinzugefügt und 
wenn das Programm geschlossen wird soll auch die Datei wieder 
geschlossen werden. Das HInzufügen von Daten funktioniert, das SChließen 
allerdings nicht, es erscheint die Meldung "global name 'datei' not 
defined"



import atexit


def exit_handler():
  datei.close()


def step_one():
  datei.write("irgendwelchedaten")
  ...


def main():
  atexit.register (exit_handler)
  datei = open ("file.txt","a")
  ...

von imonbln (Gast)


Lesenswert?

In dem von dir gezeigten Code  ist datei in jeder Funktion einen eigene 
Variable die nichts miteinander zu tun haben, die Frage welche du 
beantworten solltest ist also eher warum das Datei Write in step_one 
klappt.

Abgesehen davon wird von den meisten erfahrenen Python Entwicklern 
empfohlen das open als contextmanager zu verwenden. dann wird das Close 
beim verlassen des Context automatisch ausgeführt, auch im Fehlerfall.
1
with open ("file.txt","a") as file:
2
    step_one(file)
3
    ...

Ausserdem im  atexit noch eine Datei schließen zu wollen ist zwar 
löblich aber Zu spät. Direkt nach dem atexit kommt das OS und gibt die 
Ressourcen des Beendeten Prozess so wie so frei, dazu gehört auch das 
schließen der Datei.

Generell sollte man bei einen Software Desgin immer versuchen die 
Ressourcen an der gleichen Stelle frei zu geben, an der sie Angefordert 
werden. Es gibt ausnahmen von der Regel aber das ist (wahrscheinlich) 
keine.

von Gargamel (Gast)


Lesenswert?

ich hab nun einige Tests gemacht.
Die datei.close() Funktion führt nur zu einem Fehler, wenn sie durch 
atexit aufgerufen wird.

Ich nehme an, dass der Keyboard interrupt an sich oder der dadurch 
ausgelöste atexit u.A. bereits offene Dateien schließt bevor dann zu 
exit.handler() verwiesen wird.

von imonbln (Gast)


Lesenswert?

Gargamel schrieb:
> Ich nehme an, dass der Keyboard interrupt an sich oder der dadurch
> ausgelöste atexit u.A. bereits offene Dateien schließt bevor dann zu
> exit.handler() verwiesen wird.

Und damit unterliegst du einen Irrtum! Ein Interrupt der dir File 
Handles schließt ist ziemlich kaputt und sollte gefixet werden! Was bei 
dein Code das Problem ist kann ich dir mit den paar Zeilen die du 
gepostet hast nicht sagen , aber der Keyboard Interrupt schließt keine 
Dateien und du solltest statt mit aexit rum zu Doktoren besser das open 
als Context manager nutzen dann sind deine Problem weg.


Falls du mir das mit den Keyboard Interrupt nicht glaubst, denn kann man 
fangen und folgendes Programm sollte wenn du recht hast das datei.write 
in der letzten zeile nicht mehr ausführen können
1
if __name__ == "__main__":
2
    with open('bla.txt', 'a') as datei:
3
        try:
4
            while True:
5
                time.sleep(2)
6
                print('Hallo', file=datei)
7
        except KeyboardInterrupt:
8
            print('This is the end', file=datei)
9
        datei.write("that's all folks\n") # hier das geht!

und auf das schreiben im atexit klappt wenn trotz Keyboard interrupt.
Der Unterschied ist nur meine Variable datei ist global bei deiner weiss 
ich es nicht.
1
import time
2
import atexit
3
4
datei = open('bla2.txt', 'a')
5
6
def exit_handler():
7
  datei.write("that's all folks\n")
8
  datei.close()
9
10
if __name__ == "__main__":
11
    atexit.register(exit_handler)
12
    try:
13
        while True:
14
            time.sleep(2)
15
            print('Hallo', file=datei)
16
    except KeyboardInterrupt:
17
        print('This is the end', file=datei)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.