atexit — Exit-Handler


Das Modul atexit definiert Funktionen zur Registrierung und Deregistrierung von Bereinigungsfunktionen. Funktionen, die auf diese Weise registriert werden, werden bei normaler Beendigung des Interpreters automatisch ausgeführt. atexit führt diese Funktionen in der *umgekehrten* Reihenfolge aus, in der sie registriert wurden; wenn Sie A, B und C registrieren, werden sie bei Beendigung des Interpreters in der Reihenfolge C, B, A ausgeführt.

Hinweis: Die über dieses Modul registrierten Funktionen werden nicht aufgerufen, wenn das Programm durch ein von Python nicht behandeltes Signal beendet wird, wenn ein schwerwiegender interner Python-Fehler erkannt wird oder wenn os._exit() aufgerufen wird.

Hinweis: Das Verhalten beim Registrieren oder Deregistrieren von Funktionen aus einer Bereinigungsfunktion heraus ist undefiniert.

Geändert in Version 3.7: Bei Verwendung mit C-API-Unterinterpretern sind registrierte Funktionen auf den Interpreter beschränkt, in dem sie registriert wurden.

atexit.register(func, *args, **kwargs)

Registriert func als Funktion, die bei Beendigung ausgeführt werden soll. Alle optionalen Argumente, die an func übergeben werden sollen, müssen als Argumente an register() übergeben werden. Es ist möglich, dieselbe Funktion und dieselben Argumente mehr als einmal zu registrieren.

Bei normaler Programmbeendigung (z. B. wenn sys.exit() aufgerufen wird oder die Ausführung des Hauptmoduls abgeschlossen ist) werden alle registrierten Funktionen in LIFO-Reihenfolge aufgerufen. Die Annahme ist, dass Module auf niedrigerer Ebene normalerweise vor Modulen auf höherer Ebene importiert werden und daher später bereinigt werden müssen.

Wenn während der Ausführung der Exit-Handler eine Ausnahme ausgelöst wird, wird ein Traceback gedruckt (es sei denn, SystemExit wird ausgelöst) und die Ausnahminformationen werden gespeichert. Nachdem alle Exit-Handler ausgeführt wurden, wird die zuletzt ausgelöste Ausnahme erneut ausgelöst.

Diese Funktion gibt func zurück, was die Verwendung als Dekorator ermöglicht.

Warnung

Das Starten neuer Threads oder der Aufruf von os.fork() aus einer registrierten Funktion kann zu Race Conditions zwischen dem Haupt-Python-Runtime-Thread, der Thread-Zustände freigibt, und internen threading-Routinen oder dem neuen Prozess führen, der versucht, diesen Zustand zu verwenden. Dies kann zu Abstürzen anstelle einer sauberen Beendigung führen.

Geändert in Version 3.12: Versuche, einen neuen Thread zu starten oder einen neuen Prozess mit os.fork() in einer registrierten Funktion zu erstellen, führen nun zu RuntimeError.

atexit.unregister(func)

Entfernt func aus der Liste der Funktionen, die beim Herunterfahren des Interpreters ausgeführt werden sollen. unregister() tut stillschweigend nichts, wenn func zuvor nicht registriert wurde. Wenn func mehr als einmal registriert wurde, wird jede Instanz dieser Funktion im atexit-Aufrufstapel entfernt. Gleichheitsvergleiche (==) werden intern während der Deregistrierung verwendet, daher müssen Funktionsreferenzen keine übereinstimmenden Identitäten haben.

Siehe auch

Modul readline

Nützliches Beispiel für atexit zum Lesen und Schreiben von readline-Verlaufsdateien.

atexit Beispiel

Das folgende einfache Beispiel zeigt, wie ein Modul einen Zähler beim Importieren aus einer Datei initialisieren und den aktualisierten Wert des Zählers beim Beenden des Programms automatisch speichern kann, ohne darauf angewiesen zu sein, dass die Anwendung explizit einen Aufruf in diesem Modul bei der Beendigung macht.

try:
    with open('counterfile') as infile:
        _count = int(infile.read())
except FileNotFoundError:
    _count = 0

def incrcounter(n):
    global _count
    _count = _count + n

def savecounter():
    with open('counterfile', 'w') as outfile:
        outfile.write('%d' % _count)

import atexit

atexit.register(savecounter)

Positions- und Schlüsselwortargumente können auch an register() übergeben werden, um sie an die registrierte Funktion weiterzuleiten, wenn sie aufgerufen wird.

def goodbye(name, adjective):
    print('Goodbye %s, it was %s to meet you.' % (name, adjective))

import atexit

atexit.register(goodbye, 'Donny', 'nice')
# or:
atexit.register(goodbye, adjective='nice', name='Donny')

Verwendung als Decorator

import atexit

@atexit.register
def goodbye():
    print('You are now leaving the Python sector.')

Dies funktioniert nur mit Funktionen, die ohne Argumente aufgerufen werden können.