atexit
--- 退出處理器?
atexit
模塊定義了清理函數的注冊和反注冊函數. 被注冊的函數會(huì )在解釋器正常終止時(shí)執行. atexit
會(huì )按照注冊順序的*逆序*執行; 如果你注冊了 A
, B
和 C
, 那么在解釋器終止時(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ì )在內部使用相等性比較 (==
),因而函數引用不需要具有匹配的標識號。
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í)才能工作.