在 Flask 開啟 Debug 模式時,程序會因為自動重載(reloader)的機制而啟動兩個進程,導致if __name__ == '__main__'
底層的程序代碼被執行兩次。以下說明其原理與常見解法。
Flask Debug 模式下自動重載機制
Flask 使用的底層服務器 Werkzeug,在 Debug 模式時會啟動一個監控文件變化的子進程,主進程負責監控、子進程負責執行應用程序,當檢測到文件變更時才重新啟動子進程。這個過程中,原始程序在主進程和子進程都會運行一次,從而觸發「執行兩次」2。
當你用 debug=True 啟動 Flask 應用時,Flask 會啟用它的開發服務器,同時開啟一個自動重載功能,用來監視項目中的文件修改。一旦文件發生變動,它會自動重啟服務器。
自動重載器工作流程如下:
第一次運行(父進程): 你的腳本(
weba2f.py
)被首次執行,這個初始進程成為“監視器”或“父進程”。它會加載你的代碼,包括 if __name__ == '__main__': 塊,然后準備啟動實際的應用服務器。
第二次運行(子進程): 父進程生成一個新的“子進程”,這個子進程會重新執行你的腳本(
weba2f.py
)。這次運行是在子進程中負責實際的 Flask 應用,并處理 HTTP 請求。if __name__ == '__main__': 的代碼塊會在這個子進程中再次執行。
如何避免代碼被執行兩次(如果有必要)
如果某些代碼(例如 USD 文件的加載)不應該運行兩次,有以下幾種解決方法:
方法 1:禁用自動重載功能(失去文件變更自動重啟功能)
可以關閉自動重載器,修改 app.run 調用如下:
weba2f.py
Apply
// ...代碼其他部分...
if __name__ == '__main__':
? ? tsundere_chat = TsundereChat()
? ? # 通過 /A2F/USD/Load 加載 USD 文件到場景中
? ? url = a2fserverurl + '/A2F/USD/Load'
? ? headers = {
? ? ? ? 'accept': 'application/json',
? ? ? ? 'Content-Type': 'application/json'
? ? }
? ? data = {
? ? ? ? "file_name": usd_url
? ? }
? ? response = requests.post(url, headers=headers, json=data)
? ? # 打印響應內容
? ? print("USD 文件加載響應:", response.json())
? ??
? ? app.run(port=5000, debug=True, use_reloader=False) ?# 添加 use_reloader=False
這樣可以確保 if __name__ == '__main__': 只運行一次,但開發過程中失去了自動重載功能。