Python 为什么Flask';s app.config.from_object()与gunicorn的行为不同?

Python 为什么Flask';s app.config.from_object()与gunicorn的行为不同?,python,flask,gunicorn,Python,Flask,Gunicorn,我将Flask与virtualenv一起使用,我的演示Flask应用程序的结构如下: app/ hello.py config/ settings.py venv/ virtualenv files hello.py的内容 from flask import Flask def create_app(): app = Flask(__name__, instance_relative_config=True) app.config.from_obje

我将Flask与virtualenv一起使用,我的演示Flask应用程序的结构如下:

app/
    hello.py
config/
    settings.py
venv/
    virtualenv files
hello.py的内容

from flask import Flask


def create_app():
    app = Flask(__name__, instance_relative_config=True)
    app.config.from_object("config.settings")

    @app.route('/')
    def index():
        return app.config["HELLO"]

    return app

if __name__ == "__main__":
    app = create_app()
    app.run()
settings.py
只包含2个值

DEBUG = True
HELLO = "Hello there from /config !"
我可以使用gunicorn成功地运行它,使用
gunicorn-b0.0.0:9000--访问日志文件-“app.hello:create_app()”
,它可以正常工作,没有任何错误

但是,从root运行
python app/hello.py
会导致错误
ImportError:没有名为'config'的模块
。以这种方式执行时,flask似乎无法找到配置目录


我可以将
config
目录移动到
app
中,但这样做会导致gunicorn出现错误。难道两种方式都不能“只工作”吗?更重要的是,发生的原因和原因?

不是最优雅但仍能完美工作的解决方案:

from os.path import abspath, join
from flask import Flask


def create_app():
    app = Flask(__name__, instance_relative_config=True)
    config_file_path = abspath(
        join(app.instance_path, '../config/settings.py')
    )
    app.config.from_pyfile(config_file_path)

    @app.route('/')
    def index():
        return app.config["HELLO"]

    return app


if __name__ == "__main__":
    app = create_app()
    app.run()
在考虑该评论后添加。为了使Flask正确导入
配置设置
,应用程序根目录的路径必须位于
系统路径
内。可以通过在原始脚本中添加一行来轻松实现:

sys.path.insert(0, os.getcwd())
最后的
hello.py
如下所示:

import os
import sys
from flask import Flask


def create_app():
    app = Flask(__name__, instance_relative_config=True)
    sys.path.insert(0, os.getcwd())
    app.config.from_object("config.settings")

    @app.route('/')
    def index():
        return app.config["HELLO"]

    return app


if __name__ == "__main__":
    app = create_app()
    app.run()
更为防弹的解决方案是

app_root_path = os.path.abspath(
    os.path.join(app.instance_path, '..')
)
sys.path.insert(0, app_root_path)

这样我们就不依赖于os.getcwd()返回的内容:它并不总是必须返回应用程序根路径

是否将
\uuuu init\uuuuu.py
文件添加到配置中,使其成为一个包,帮助?我先前尝试将一个空的
\uuuuuuu init\uuuuuuuuu.py
添加到
配置/
中,但没有帮助。出现相同错误。您可以尝试手动导入config.settings,然后使用from_对象(config.settings)。也许古尼康真的操纵了蟒蛇。您可以尝试将文件夹添加到pythonpath,以便导入config.settings。(手动导入不应更改任何内容,但您可能会看到无法导入设置模块。)嗯,您是对的。在导出PYTHONPATH=$PYTHONPATH:.之后,
python应用程序/hello.py
就可以工作了。我认为删除
instance\u relative\u config=True
部分就可以了……啊,我明白你在那里做了什么。奇怪的是,
os.getcwd()
实际上返回了应用程序根目录,但不知何故,
app.config.from_object(“config.settings”)
不起作用。@paonicles您的评论让我明白,
os.getcwd()
必须在
sys.path
中才能进行导入。我编辑了我的答案来反映这个想法。更准确地说,为了导入工作,应用程序的根路径必须在
sys.path
中。@arrakis_sun有一个
Flask.root_path
@Shankar在本例中
app.root_path
app.instance_path
返回相同的内容