atexit
--- 退出處理器?
atexit
模塊定義了清理函數(shù)的注冊和反注冊函數(shù). 被注冊的函數(shù)會在解釋器正常終止時執(zhí)行. atexit
會按照注冊順序的*逆序*執(zhí)行; 如果你注冊了 A
, B
和 C
, 那么在解釋器終止時會依序執(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)識號。
atexit
示例?
以下簡單例子演示了一個模塊在被導(dǎo)入時如何從文件初始化一個計(jì)數(shù)器,并在程序終結(jié)時自動保存計(jì)數(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)用時才能工作.