为什么运行 Flask 开发服务器会自行运行两次?

问题描述 投票:0回答:8

我正在使用 Flask 来开发网站,在开发过程中我使用以下文件运行 Flask:

#!/usr/bin/env python
from datetime import datetime
from app import app
import config

if __name__ == '__main__':
    print('################### Restarting @', datetime.utcnow(), '###################')
    app.run(port=4004, debug=config.DEBUG, host='0.0.0.0')

当我启动服务器时,或者当它因文件已更新而自动重新启动时,它总是显示打印行两次:

################### Restarting @ 2014-08-26 10:51:49.167062 ###################
################### Restarting @ 2014-08-26 10:51:49.607096 ###################

虽然这并不是真正的问题(其余部分按预期工作),但我只是想知道为什么它会这样?有什么想法吗?

python flask
8个回答
239
投票

Werkzeug 重新加载器会生成一个子进程,以便每次代码更改时它都可以重新启动该进程。 Werkzeug 是当您调用

app.run()
时为 Flask 提供开发服务器的库。

参见

restart_with_reloader()
功能代码;您的脚本将再次运行 subprocess.call()
如果您将 

use_reloader

设置为

False
,您会看到该行为消失,但您也会失去重新加载功能:
app.run(port=4004, debug=config.DEBUG, host='0.0.0.0', use_reloader=False)

您也可以在使用 
flask run

命令时禁用重新加载器:

FLASK_DEBUG=1 flask run --no-reload

如果您想检测何时处于重新加载子进程中,可以使用 

werkzeug.serving.is_running_from_reloader 函数

from werkzeug.serving import is_running_from_reloader if is_running_from_reloader(): print(f"################### Restarting @ {datetime.utcnow()} ###################")

但是,如果您需要设置模块全局变量,那么您应该在函数上使用 

@app.before_first_request 装饰器

 并让该函数设置此类全局变量。当第一个请求到来时,每次重新加载后它都会被调用一次:
@app.before_first_request def before_first_request(): print(f"########### Restarted, first request @ {datetime.utcnow()} ############")

请务必考虑到,如果您在使用分叉或新子流程来处理请求的全面 WSGI 服务器中运行此程序,则每个新子流程都会调用 
before_first_request

处理程序

可能


19
投票
flask run

命令,则不会使用

app.run
的任何选项。要完全禁用重新加载器,请传递
--no-reload
:

FLASK_DEBUG=1 flask run --no-reload

此外,
__name__ == '__main__'

永远不会为真,因为应用程序不是直接执行的。使用

Martijn 的答案
中的相同想法,除了没有 __main__ 块。

if os.environ.get('WERKZEUG_RUN_MAIN') != 'true': # do something only once, before the reloader if os.environ.get('WERKZEUG_RUN_MAIN') == 'true': # do something each reload



10
投票
app.debug

设置为

False
来解决它。将其设置为
True
会导致我的
__name__ == "__main__"
被调用两次。
    


7
投票
flask run

而不是

python application.py
运行应用程序。使用后者可能会导致代码运行两次。

如此处所述

...从 Flask 0.11 开始,推荐使用 Flask 方法。这样做的原因是,由于重新加载机制的工作方式,会产生一些奇怪的副作用(例如执行某些代码两次......)


2
投票

FLASK_RUN_RELOAD=假

这将避免我的烧瓶运行两次。


1
投票

if __name__ == '__main__': app.run(debug=True, use_reloader=False)



0
投票
WEB_CONCURRENCY

设置的配置。要设置为一个,您可以在控制台中编写

heroku config:set WEB_CONCURRENCY=1
    


0
投票

import os.path from apscheduler.schedulers.background import BackgroundScheduler def set_lastrun(): f = open('/tmp/lastrun','w') f.write(f'{datetime.now()}') f.close() def get_lastrun(): return os.path.isfile('/tmp/lastrun') def start_job_scheduler(): scheduler = BackgroundScheduler() scheduler.add_job(func=your_job, trigger="interval", seconds=300) scheduler.start() app = Flask(__name__) def app_init(): if not get_lastrun(): set_lastrun() start_job_scheduler()

`

© www.soinside.com 2019 - 2024. All rights reserved.