atexit — 退出處理器


atexit 模組定義了用於註冊和取消註冊清理函式的函式。 如此註冊的函式會在直譯器正常終止時自動執行。 atexit 會按註冊順序的相反順序執行這些函式;如果註冊了 ABC,則在直譯器終止時,它們將按 CBA 的順序執行。

注意: 當程式被 Python 未處理的訊號終止、檢測到 Python 致命內部錯誤或呼叫 os._exit() 時,不會呼叫透過此模組註冊的函式。

注意: 在清理函式內部註冊或取消註冊函式的效果是未定義的。

在 3.7 版本中更改: 當與 C-API 子直譯器一起使用時,註冊的函式是它們註冊的直譯器本地的。

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

func 註冊為在終止時執行的函式。 要傳遞給 func 的任何可選引數都必須作為 register() 的引數傳遞。 可以多次註冊相同的函式和引數。

在程式正常終止時(例如,如果呼叫了 sys.exit() 或主模組的執行完成),所有註冊的函式都將按後進先出的順序呼叫。 假設較低級別的模組通常會在較高級別的模組之前匯入,因此必須在稍後進行清理。

如果在退出處理程式的執行過程中引發異常,則會列印回溯(除非引發 SystemExit),並且會儲存異常資訊。 在所有退出處理程式都有機會執行後,將重新引發最後一個引發的異常。

此函式返回 func,這使得可以將其用作裝飾器。

警告

從註冊的函式啟動新執行緒或呼叫 os.fork() 可能會導致主 Python 執行時執行緒釋放執行緒狀態與內部 threading 例程或新程序嘗試使用該狀態之間的競爭條件。 這可能導致崩潰,而不是乾淨的關閉。

在 3.12 版本中更改: 嘗試在註冊的函式中啟動新執行緒或 os.fork() 新程序現在會導致 RuntimeError

atexit.unregister(func)

從在直譯器關閉時執行的函式列表中刪除 func。 如果 func 之前未註冊,unregister() 會靜默地執行任何操作。 如果 func 已多次註冊,則 atexit 呼叫堆疊中的該函式的每次出現都將被刪除。 在取消註冊期間,內部使用相等比較 (==),因此函式引用不需要具有匹配的標識。

另請參閱

模組 readline

atexit 的有用示例,用於讀取和寫入 readline 歷史檔案。

atexit 示例

以下簡單示例演示了模組如何在匯入時從檔案初始化計數器,並在程式終止時自動儲存計數器的更新值,而無需依賴應用程式在終止時顯式呼叫此模組。

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)

位置引數和關鍵字引數也可以傳遞給 register(),以便在呼叫註冊函式時傳遞給該函式

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')

用作 裝飾器

import atexit

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

這僅適用於可以不帶引數呼叫的函式。