Flask应用运行后调用函数的正确方法是什么?

33 投票
3 回答
28151 浏览
提问于 2025-04-17 13:00

我有点困惑,想做的事情看起来应该很简单。我写了一个用 Flask 制作的简单应用,代码大概是这样的:

from flask import Flask

app = Flask(__name__)

def _run_on_start(a_string):
    print "doing something important with %s" % a_string

@app.route('/')
def root():
    return 'hello world'

if __name__ == "__main__":
    if len(sys.argv) < 2:
        raise Exception("Must provide domain for application execution.")
    else:
        DOM = sys.argv[1]
        _run_on_start("%s" % DOM)
        app.run(debug=True)

我发现我的终端输出了 _run_on_start 里的打印信息,但其他通常的 Flask 应用调试信息却没有。如果我在调用 app.run 之前去掉这个调用,输出就正常了。而且我发现 _run_on_start 的输出在启动时重复了两次,我不确定这是奇怪的输出,还是这个函数真的被调用了两次。

我在想,这可能不是在调用 app.run 之前添加函数调用的正确方法。我查阅了 Flask 的文档,发现提到了一些装饰器,可以在某些请求之前或之后执行函数,但我想在应用服务器运行时执行这个调用。

此外,我意识到如果我从另一个模块调用这个模块,也就是当 __name__ != "__main__" 时,我就不会得到对 _run_on_start 的调用。

那么在这两种情况下,从命令行启动和从另一个模块启动,正确的方法是什么呢?

3 个回答

1

在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。这些问题可能会让我们感到困惑,不知道该怎么解决。比如,有人可能在使用某个特定的功能时,发现它没有按照预期工作,或者出现了错误信息。这种情况下,我们通常会去查找相关的资料,看看有没有人遇到过类似的问题,或者在网上的技术论坛上寻求帮助。

在这些论坛上,很多人会分享他们的经验和解决方案,帮助其他人理解问题的根源以及如何解决它们。通过这些讨论,我们可以学到很多实用的知识,避免在同样的地方踩坑。

总之,遇到问题时,不要害怕去寻求帮助,很多时候,别人已经遇到过类似的情况,并且找到了解决办法。

from flask import Flask

def create_app():
    app = Flask(__name__)
    def run_on_start(*args, **argv):
        print "function before start"
    run_on_start()
    return app

app = create_app()

@app.route("/")
def hello():
    return "Hello World!"
49

你可能是在寻找 Flask.before_first_request 这个装饰器,像这样:

@app.before_first_request
def _run_on_start(a_string):
    print "doing something important with %s" % a_string
16

你看到的函数重复输出是因为重载器的原因。重载器的第一个工作就是在一个新的线程中启动主函数,这样它就可以监控源文件的变化,并在文件变化时重新启动这个线程。如果你不想要这种行为,可以通过设置 use_reloader=False 来关闭它。

如果你想在从其他模块启动服务器时能够运行你的函数,可以把它放在一个函数里,然后在其他模块中调用这个函数:

def run_server(dom):
        _run_on_start("%s" % dom)
        app.run(debug=True, use_reloader=False)

if __name__ == '__main__':
    if len(sys.argv) < 2:
        raise Exception("Must provide domain for application execution.")
    else:
        DOM = sys.argv[1]
        run_server(DOM)

至于“正确的方法”是什么,这要看你到底想实现什么。内置的服务器是用来在本地测试环境中运行你的应用程序的,目的是在你把它部署到生产服务器之前进行测试。所以,从其他模块启动它的问题本身并没有太大意义。

撰写回答