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

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

输出: >

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

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

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

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

1. 取消自动重启

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

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

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

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

1
new_environ['WERKZEUG_RUN_MAIN'] = 'true'

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

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

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

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

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

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

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

(全文完)

参考:

留言

2017-04-21
次访问