Flask 在 Debug 模式下初始化2次

Flask 在 Debug 模式下启动的时候,会被初始化两次。看下面的代码:

1from app import app
2import time
3
4if __name__ == '__main__':
5    print(time.time())
6    app.run(port=5000, debug=True)

输出:

11492742262.002537
2 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
3 * Restarting with stat
41492742262.598912
5 * Debugger is active!
6 * Debugger pin code: xxx-xxx-xxx

这将导致我们的某些需要在初始化时执行的方法被执行2次,这显然不是我们需要的结果。

出现这样的问题的原因是在开启 Debug 模式的时候,Werkzeug 默认会 启动一个额外的进程 来监控文件变化以方便重启进程。

要解决这个启动两次的问题,有这样几种方法:

1. 取消自动重启

在 Debug 模式下,为了方便调试,Flask 提供了当文件变化的时候自动重启实例的功能。关闭这个功能就可以避免初始化2次的情况。

1app.run(port=5000, debug=True, use_reloader=False)

2. 判断 Werkzeug 主进程是否执行

restart_with_reloader function 中,我们可以看到在新进程启动前,环境变量 WEAKZEUG_RUN_MAIN 被置为 'true'

1new_environ['WERKZEUG_RUN_MAIN'] = 'true'

通过判断这个变量的值,我们就能保证在启动时仅执行一次:

1if __name__ == '__main__':
2    import os
3    if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
4        print(time.time())
5    app.run(port=5000, debug=config.DEBUG)

3. 在第一次请求的时候执行

使用 before_first_request 这个钩子,把执行放在 Flask 第一次收到请求的时候。这就避免了2次初始化的干扰。

1@app.before_first_request
2def initialize():
3    print(time.time())

4. 在需要请求的时候执行

和“在第一次请求的时候执行”类似,使用一个开关变量,控制执行仅一次。把执行延迟到了应用逻辑层面。

(全文完)

参考: