atexit --- 退出處理器?


atexit 模塊定義了清理函數(shù)的注冊和反注冊函數(shù). 被注冊的函數(shù)會在解釋器正常終止時執(zhí)行. atexit 會按照注冊順序的*逆序*執(zhí)行; 如果你注冊了 A, BC, 那么在解釋器終止時會依序執(zhí)行 C, B, A.

注意: 通過該模塊注冊的函數(shù), 在程序被未被 Python 捕獲的信號殺死時并不會執(zhí)行, 在檢測到 Python 內(nèi)部致命錯誤以及調(diào)用了 os._exit() 時也不會執(zhí)行.

在 3.7 版更改: 當(dāng)配合 C-API 子解釋器使用時,已注冊函數(shù)是它們所注冊解釋器中的局部對象。

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

func 注冊為終止時執(zhí)行的函數(shù). 任何傳給 func 的可選的參數(shù)都應(yīng)當(dāng)作為參數(shù)傳給 register(). 可以多次注冊同樣的函數(shù)及參數(shù).

在正常的程序終止時 (舉例來說, 當(dāng)調(diào)用了 sys.exit() 或是主模塊的執(zhí)行完成時), 所有注冊過的函數(shù)都會以后進(jìn)先出的順序執(zhí)行. 這樣做是假定更底層的模塊通常會比高層模塊更早引入, 因此需要更晚清理.

如果在 exit 處理句柄執(zhí)行期間引發(fā)了異常,將會打印回溯信息 (除非引發(fā)的是 SystemExit) 并且異常信息會被保存。 在所有 exit 處理句柄都獲得運(yùn)行機(jī)會之后,所引發(fā)的最后一個異常會被重新引發(fā)。

這個函數(shù)返回 func 對象,可以把它當(dāng)作裝飾器使用。

atexit.unregister(func)?

func 移出當(dāng)解釋器關(guān)閉時要運(yùn)行的函數(shù)列表。 如果 func 之前未被注冊則 unregister() 將靜默地不做任何事。 如果 func 已被注冊一次以上,則該函數(shù)每次在 atexit 調(diào)用棧中的出現(xiàn)都將被移除。 當(dāng)取消注冊時會在內(nèi)部使用相等性比較 (==),因而函數(shù)引用不需要具有匹配的標(biāo)識號。

參見

模塊 readline

使用 atexit 讀寫 readline 歷史文件的有用的例子。

atexit 示例?

以下簡單例子演示了一個模塊在被導(dǎo)入時如何從文件初始化一個計數(shù)器,并在程序終結(jié)時自動保存計數(shù)器的更新值,此操作不依賴于應(yīng)用在終結(jié)時對此模塊進(jìn)行顯式調(diào)用。:

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)

位置和關(guān)鍵字參數(shù)也可傳入 register() 以便傳遞給被調(diào)用的已注冊函數(shù):

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

作為 decorator: 使用:

import atexit

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

只有在函數(shù)不需要任何參數(shù)調(diào)用時才能工作.