这是另一个烧瓶开发服务器重新加载器问题。有一百万个问题问为什么它会两次加载所有内容,而这不是其中之一。我知道它会加载所有内容两次,我的问题涉及处理这个现实,我还没有找到我认为解决我正在尝试做的事情的答案。
我的问题是,如何在退出时清理所有应用程序对象?
我目前的方法如下所示。在此示例中,我使用 atexit 函数运行我的清理代码。
from flask import Flask
app = Flask(__name__)
print("start_app_id: ", '{}'.format(id(app)))
import atexit
@atexit.register
def shutdown():
print("AtExit_app_id: ", '{}'.format(id(app)))
#do some cleanup on the app object here
if __name__ == "__main__":
import os
if os.environ.get('WERKZEUG_RUN_MAIN') == "true":
print("reloaded_main_app_id: ", '{}'.format(id(app)))
else:
print("first_main_app_id: ", '{}'.format(id(app)))
app.run(host='0.0.0.0', debug=True)
这段代码的输出如下:
start_app_id: 140521561348864
first_main_app_id: 140521561348864
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
start_app_id: 140105598483312
reloaded_main_app_id: 140105598483312
* Debugger is active!
* Debugger pin code: xxx-xxx-xxx
^CAtExit_app_id: 140521561348864
请注意,首次加载时,会创建一个 ID 为 '864 的应用程序对象。在自动重新加载期间,会创建一个 ID 为 '312 的新应用程序对象。然后,当我按下 Ctrl-C(最后一行)时,将调用 atexit 例程,原始的 '864 app 对象是可以使用 app 变量访问的对象,而不是较新的 '312 app 对象。
我希望能够在服务器关闭或 Ctrl-C 时(在本例中为 '864 和 '312)对浮动的所有应用程序对象进行清理。关于如何做到这一点的任何建议?
或者,如果我可以在重新加载后创建的较新的 '312 对象上运行清理,我也可以完成这项工作 - 但是我目前的方法只能让我清理原始应用程序对象。
谢谢。
UPDATE1:我发现了一个链接,建议使用 try/finally 而不是 atexit 挂钩来完成我上面打算做的事情。切换到此会导致与 atexit 完全相同的行为,因此对我的问题没有帮助:
from flask import Flask
app = Flask(__name__)
print("start_app_id: ", '{}'.format(id(app)))
if __name__ == "__main__":
import os
if os.environ.get('WERKZEUG_RUN_MAIN') == "true":
print("reloaded_main_app_id: ", '{}'.format(id(app)))
else:
print("first_main_app_id: ", '{}'.format(id(app)))
try:
app.run(host='0.0.0.0', debug=True)
finally:
print("Finally_app_id: ", '{}'.format(id(app)))
#do app cleanup code here