Flask最佳实践
Posted Python之美
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask最佳实践相关的知识,希望对你有一定的参考价值。
这是「写个抓取网易云音乐精彩评论的爬虫」的续篇。本节将主要分享 https://github.com/dongweiming/commentbox 中我使用Flask的考虑以及延伸出来的问题。
1. 怎么用扩展
在Application Factories提到了如何用扩展,也就是在create_app内才用init_app初始化对应的扩展。但是我推荐如下方式来组织扩展。首先 创建一个ext.py(叫extensions.py或者其他我也不反对)文件,用来管理全部的扩展:
同样在create_app里面初始化(https://github.com/dongweiming/commentbox/blob/master/app.py#L18):
举个例子,注意其中的db,我没有用 「from yourapplication.model import db」,而是使用了第三方的ext中import进来的。
而在model里面怎么用呢(https://github.com/dongweiming/commentbox/blob/master/models.py#L24):
这样就解耦了扩展的使用,也就是不会有相互依赖的问题了,这就是init_app存在的意义。
2. 自定义RESTAPI的处理
现存的框架比较知名的有django-rest-framework和flask-restapi,但是这些框架我都不太满意,而对于我这个项目用它们还太重了。好吧,手动写一个实现。首先是借用 DispatcherMiddleware 实现对/j这样的路径特殊处理(https://github.com/dongweiming/commentbox/blob/master/app.py#L23):
我希望/j开头的返回的响应都是json格式的内容:
其中返回了一个额外的字段r, 如果是0表示响应的结果是正确的,为1表示响应的内容有问题。
接着我们自定义错误处理的方式,比如404返回这样:
怎么实现呢:
而且响应也被封装了:
使用的时候可以让返回的正确和错误结果的格式都保持统一。
3. Redis序列化
我使用了mongoengine处理model,但是为了给后端减少压力,所以使用Redis缓存结果。大家知道Redis支持了很多数据结构,对我来说,其实是可以满足的,但是为了演示如何存储复杂对象,单个文档对象缓存的是序列化之后的结果,也就是一个字符串(https://github.com/dongweiming/commentbox/blob/master/models.py#L42):
cache.set(key, rs.to_json())
取的时候这样用:
其中from_json和to_json都是mongoengine自带的,希望对大家在业务中的使用有启发。
4. local_settings.py
local_settings.py在豆瓣被广泛的使用,一般的Flask应用都会有一个config.py文件,包含一些配置,它会被放进版本库。但是线上和测试环境其中的一些设置是不一样的,比如DEBUG在线上一定是False,但是在测试环境就是True。 那么可以在config.py这么用(https://github.com/dongweiming/commentbox/blob/master/config.py#L17):
假如存在local_settings.py,那么配置就被会覆盖了,而local_settings.py就是在特定环境下才存在的。
5. 使用Mako
豆瓣在我印象里面好像都是没人使用Jinja2的。Mako是另一个知名模板语言,它有如下优点:
1. 性能和Jinja2相近,这一点Jinja2也承认。
2. 有大型网站在使用,有质量保证。Reddit在2011年的月PV就达到10亿,豆瓣几乎全部用户产品都使用Mako模板,所以不需要担心没有大公司使用的案例。
3. 有知名Web框架支持。Pylons和Pyramid这两个Web框架内置Mako,而且把它作为默认模板。
4. 支持在模板中写几乎原生的Python语法的代码,对Python工程师友好,我已经见过多个人来了豆瓣爱上Mako而抛弃Jinja2的例子了。
5. 自带完整的缓存系统。Mako提供非常好的扩展接口,很容易切换成其他的缓存系统。
Jinja2和Mako的设计哲学有一点不同:Jinja2认为应该尽可能把逻辑从模板中移除,界限清晰,不允许在模板内写Python代码,也不支持全部的Python内置函数(只提供了很有限、最常用的一部分);而Mako正好相反,它最后会编译成Python代码以达到性能最优,在模板里面可以自由写后端逻辑,不需要传递就可以使用Python自带的数据结构和内置类。Jinja2带来的好处是模板引擎易于维护,并且模板有更好的可读性;而Mako是一个对Python工程师非常友好的语言,限制很少,完成模板开发工作时更有效率,整个项目的代码可维护性更好。
6. 合理使用Flask提供的资源
这并不是这个项目中用到的实践。我在豆瓣东西的一个后台项目看到过这样用蓝图:
其实好的做法是什么呢:
是否懂了呢?
以上是关于Flask最佳实践的主要内容,如果未能解决你的问题,请参考以下文章
最佳实践从 0 开始,用 flask+mongodb 打造分布式服务器监控平台