atexit --- 退出處理器?


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

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

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

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

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

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

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

這個(gè)函數返回 func 對象,可以把它當作裝飾器使用。

atexit.unregister(func)?

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

參見(jiàn)

模塊 readline

使用 atexit 讀寫(xiě) readline 歷史文件的有用的例子。

atexit 示例?

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

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)鍵字參數也可傳入 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')

作為 decorator: 使用:

import atexit

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

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