Python atexit 模組

Posted on  Sep 21, 2019  in  Python 程式設計 - 初階  by  Amo Chen  ‐ 2 min read

最近在看 Elastic APM agent for Python 的原始碼時,看到該專案的開發者有使用 atexit 模組,在 APM agent 關閉前先關閉 metrics collect timer 。

由於對 atexit 不甚熟悉,因此特以此文研究一番。

本文環境

  • Python 3.6.5

Exit handlers

The atexit module defines functions to register and unregister cleanup functions.

atexit 模組可以讓我們註冊(register)或取消(unregister)程式結束時(更嚴格的說是 Python 直譯器 / interpreter 結束執行之前)要執行的函數,,這些函數通常是用來進行收尾的程式,所以被稱為 cleanup functions ,例如關閉連線、關閉檔案等等。

例如以下範例,會在程式結束時列印 Goodbye :

import atexit


def main():
    for x in range(10):
        print(x)


@atexit.register
def print_goodbye():
    print('Goodbye')
    

if __name__ == '__main__':
    main()

以下為上述程式的執行結果,可以看到 main() 函式中沒有 print('Goodbye') 但是最後仍印出 Goodbye 的字串,這就是 atexit 模組的用途,讓程式在結束前執行指定的函式:

0
1
2
3
4
5
6
7
8
9
Goodbye

執行順序

atexit 也支援註冊多個函式:

import atexit


def A():
    print('A')
    

def B():
    print('B')
    
    
def C():
    print('C')
    

if __name__ == '__main__':
   atexit.register(A)
   atexit.register(B)
   atexit.register(C)

上述執行結果:

C
B
A

如果註冊多個函式時,函式的執行順序會是註冊順序的相反:

atexit runs these functions in the reverse order in which they were registered; if you register A, B, and C, at interpreter termination time they will be run in the order C, B, A.

atexit 注意事項

The functions registered via this module are not called when the program is killed by a signal not handled by Python, when a Python fatal internal error is detected, or when os._exit() is called.

官方文件記載, atexit 有 3 種情況會無法執行:

  1. 被程式沒處理到的 signal kill
  2. 發生 Python 內部嚴重的錯誤時,例如 Python 本身的 bug
  3. 呼叫 os._exit()

例如:

import atexit

import os


def A():
    print('A')


if __name__ == '__main__':
    atexit.register(A)
    os._exit(1)

上述範例,不會執行 atexit 所註冊的函式,因為使用到 os._exit(1)

或者我們以指令 kill -9 <pid> 停止執行以下程式時,也不會執行 atexit

import atexit
from time import sleep


def A():
    print('A')


if __name__ == '__main__':
    atexit.register(A)
    while True:
        print(1)
        sleep(10)

以上,就是 Python atexit 模組的簡單說明囉。

References

https://docs.python.org/3/library/atexit.html

對抗久坐職業傷害

研究指出每天增加 2 小時坐著的時間,會增加大腸癌、心臟疾病、肺癌的風險,也造成肩頸、腰背疼痛等常見問題。

然而對抗這些問題,卻只需要工作時定期休息跟伸展身體即可!

你想輕鬆改變現狀嗎?試試看我們的 PomodoRoll 番茄鐘吧! PomodoRoll 番茄鐘會根據你所設定的專注時間,定期建議你 1 項辦公族適用的伸展運動,幫助你打敗久坐所帶來的傷害!

贊助我們的創作

看完這篇文章了嗎? 休息一下,喝杯咖啡吧!

如果你覺得 MyApollo 有讓你獲得實用的資訊,希望能看到更多的技術分享,邀請你贊助我們一杯咖啡,讓我們有更多的動力與精力繼續提供高品質的文章,感謝你的支持!