Flask析构函数

4

我正在使用Flask构建一个Web应用程序。我已经对Flask对象进行了子类化,以便在应用程序退出之前( Flask对象被销毁)执行一段代码。当我在终端中运行它并按下^ C时,我没有看到" Can you hear me? "消息,因此我认为__del__()没有被调用。

from flask import Flask

class MyFlask (Flask):

  def __init__(self, import_name, static_path=None, static_url_path=None,
                     static_folder='static', template_folder='templates',
                     instance_path=None, instance_relative_config=False):

    Flask.__init__(self, import_name, static_path, static_url_path,
                         static_folder, template_folder,
                         instance_path, instance_relative_config)

    # Do some stuff ... 

  def __del__(self):
    # Do some stuff ... 
    print 'Can you hear me?'

app = MyFlask(__name__)

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

if __name__ == "__main__":
  app.run()

我希望这段代码能在析构函数中执行,以便无论应用程序如何加载都能运行。例如,在测试中运行app.run(),在生产环境中运行gunicorn hello.py。谢谢!

3
在你的脚本中,最好使用信号来捕获程序结束。 - korylprince
不错的想法。捕捉 SIGINT 很容易,但我需要研究一下代码部署时将使用哪些信号。这将被放在 Heroku 上。 - tweaksp
2个回答

6
也许这是可能的:
if __name__ == '__main__':
    init_db()  #or what you need
    try:
        app.run(host="0.0.0.0")
    finally:
        # your "destruction" code
        print 'Can you hear me?'

然而,我不知道您是否仍然可以在 finally 块中使用 app ...


1
这是最佳解决方案,是的,在 finally 块中仍然可以完全使用 app 对象。 - Markus Unterwaditzer

4

代码只会引用实例本身,不会使用全局变量。 - tweaksp
@Chris:它调用了Flask.__del__Flask是一个全局变量。 - user2357112
啊,我明白了。但是如果省略了这个,析构函数怎么可能不被调用呢?是不是还有其他东西在最后一秒钟引用了 app - tweaksp
@Chris:当你的脚本结束时,app变量仍然存在。 - user2357112
当然会的,但是在输入^C后,它的引用计数应该降为0。我猜测这可能与WSGI有关。 - tweaksp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接