使用 Shell

Changelog

0.3 新版功能.

人们喜爱 Python 的原因之一就是它交互式的 shell。它基本上允许你实时地执行 Python 指令并立即获得反馈结果。 Flask 本身并没有附带一个交互式的 shell,因为它并不需要任何具体的前置条件,你只需要导入你的程序就可以愉快地玩耍了。

不过依然存在一些便利的辅助工具,它们使得你使用 shell 的体验更加愉快。交互式的控制台中的主要问题是你不能像浏览器一样触发一个请求,即无法使用 grequest 等对象。但假如你写的代码依赖它们来进行调试,那么你应该怎么做呢?

这就是一些辅助函数大展拳脚的场景了。不过请牢记,这些函数不仅适用于交互式 shell 的场景下,还能用于单元测试以及其他需要伪造请求的情况。

Generally it’s recommended that you read 请求上下文 first.

命令行接口

自 Flask 0.11 开始,推荐使用 flask shell 命令来使用 shell ,它能为你自动完成许多工作。比如自动地为你初始化一个 shell 并加载好应用上下文。

更多信息可以查阅 Command Line Interface

创建一个请求上下文

在 shell 中创建一个正确的请求上下文最简单的方法就是使用 test_request_context 方法,它能为我们创建一个 RequestContext:

>>> ctx = app.test_request_context()

通常来说你会使用 with 语句来激活请求对象,不过在 shell 中更方便的做法是手动调用 push()pop() 方法:

>>> ctx.push()

从这时开始,直到调用 pop 之前,你可以使用请求对象:

>>> ctx.pop()

触发请求前/后的动作

仅仅创建请求上下文还不够,你还没有执行请求前的一般会执行的动作。假如在请求前的钩子中包含了连接数据库的操作,这会导致你的数据库仍不可用,这么做还有可能导致当前用户没有被存储在 g 中等一系列错误。

我们可以很轻松地解决这个问题。只要调用 preprocess_request() 就可以了:

>>> ctx = app.test_request_context()
>>> ctx.push()
>>> app.preprocess_request()

请记住,preprocess_request() 函数可能会返回一个响应对象,但在这种情况下,忽略这个返回值就好了。

如果要关闭一个请求,你需要在请求后钩子函数(由 process_response() 触发)作用于响应对象前将它关闭:

>>> app.process_response(app.response_class())
<Response 0 bytes [200 OK]>
>>> ctx.pop()

注册为 teardown_request() 的函数会在请求上下文弹出后自动执行。所以,在这里释放之前由请求上下文申请的资源(比如数据库连接)就相当合适了。

提升 Shell 使用体验

如果你喜欢使用 shell 的感觉,你还可以为你自己创建一个包含你想要全部导入内容的模块。你可以在那里定义一些操纵常见资源的辅助方法,比如初始化数据库,删除表等等。

你只需将它们放入一个模块(比如 shelltools)并将其导入即可:

>>> from shelltools import *