atexit
— 退出處理器¶
atexit
模組定義了用於註冊和取消註冊清理函式的函式。 如此註冊的函式會在直譯器正常終止時自動執行。 atexit
會按註冊順序的相反順序執行這些函式;如果註冊了 A
、B
和 C
,則在直譯器終止時,它們將按 C
、B
、A
的順序執行。
注意: 當程式被 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
呼叫堆疊中的該函式的每次出現都將被刪除。 在取消註冊期間,內部使用相等比較 (==
),因此函式引用不需要具有匹配的標識。
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.')
這僅適用於可以不帶引數呼叫的函式。