atexit --- 退出處理器?


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

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

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

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

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

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

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

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

atexit.unregister(func)?

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

參見(jiàn)

模塊 readline

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

atexit 示例?

以下簡(jiǎn)單例子演示了一個(gè)模塊在被導(dǎo)入時(shí)如何從文件初始化一個(gè)計(jì)數(shù)器,并在程序終結(jié)時(shí)自動(dòng)保存計(jì)數(shù)器的更新值,此操作不依賴于應(yīng)用在終結(jié)時(shí)對(duì)此模塊進(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)用的已注冊(cè)函數(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)用時(shí)才能工作.