flask 源码解析:简介

文章属于做者原创,原文发布在我的博客html

flask 简介

Flask 官网上对它的定位是一个“微” python web 开发框架。python

Flask is a micro web development framework for Python.linux

python 语言 web 框架不少:Django、Tornado、webpy、bottle……,flask 的特色是简单可扩展。简单有几个方面,好比它只实现 web 框架最核心的功能,保持功能的简洁;还有一个就是代码量少,核心代码 app.py 文件只有 2k+ 行。可扩展就是容许第三方插件来扩充功能,好比数据库可使用 Flask-SQLAlchemy,缓存可使用 Flask-Cache 等等。web

下面这段代码是 flask 官方文档给出的 hello world 版本的 flask 应用:数据库

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

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

要理解 flask 的源码,必须有必定的 python 基础(对 decorator、magic method、iterator、generator 概念比较熟悉),否则的话,会有些吃力。另一个必须理解的概念是 WSGI,简单来讲就是一套 web server 和 web 框架/web 应用之间的协议。能够阅读我以前写的 python wsgi 简介 和翻译的 什么是 web 框架 ,或者自行搜索相关资料,熟悉这部分的内容。json

NOTE:本系列文章分析的 flask 版本号是 0.12,其余版本可能会有出入。flask

两个依赖

flask 有两个核心依赖库:werkzeugjinja,而 werkzeug 又是二者中更核心的。缓存

werkzeug 负责核心的逻辑模块,好比路由、请求和应答的封装、WSGI 相关的函数等;jinja 负责模板的渲染,主要用来渲染返回给用户的 html 文件内容。restful

模板(template)是和 web 框架相对独立的内容,好比 jinja 不是只能用在 web 应用中,而 web 应用也能够不处理模板(好比返回 raw text 或者 json/xml 结构数据,而不是 html 页面)。flask 直接使用 jinja2 而不是把这部分也作成可扩展的看起来有悖它的设计原则,我我的的理解是:flask 是个写网页的 web 框架,不像 flask-restful 能够专门作 json/xml 数据接口,必须提供模板功能,否则用户就没法使用。而若是不绑定一个模板库的话,有三种方法:本身写一个模板引擎、封装一个可扩展的模板层,用户能够本身选择具体的模板引擎、或者让用户本身处理模板。可是这些方法要么增长实现的复杂度,要么增长了使用的复杂度。网络

werkzeug

werkzeug 的定位并非一个 web 框架,而是 HTTP 和 WSGI 相关的工具集,能够用来编写 web 框架,也能够直接使用它提供的一些帮助函数。

Werkzeug is an HTTP and WSGI utility library for Python.

werkzeug 提供了 python web WSGI 开发相关的功能:

  • 路由处理:怎么根据请求中的 url 找到它的处理函数

  • request 和 response 封装:能够更好地读取 request 的数据,也容易生成响应

  • 一个自带的 WSGI server,能够用来测试环境运行本身的应用

好比,咱们可使用 werkzeug 编写一个简单的 hello world 的 WSGI app:

from werkzeug.wrappers import Request, Response

def application(environ, start_response):
    request = Request(environ)
    text = 'Hello %s!' % request.args.get('name', 'World')
    response = Response(text, mimetype='text/plain')
    return response(environ, start_response)

除了和 web WSGI 相关的功能,werkzeug 还实现了不少很是有用的数据结构和函数。好比用来处理一个 key 对应多个值的 MultiDict,不支持修改的字典 ImmutableDict ,能够缓存类属性的 cache_property 等等。若是有机会,能够写篇文章讲讲 werkzeug 的源码(好吧,我又挖坑了)。

Jinja2

官网上,对 Jinja 的 介绍已经很清晰,它就是一个 python 实现的模板引擎,功能很是丰富。

Jinja2 is a full featured template engine for Python. It has full unicode support, an optional integrated sandboxed execution environment, widely used and BSD licensed.

Jinja 功能比较丰富,支持 unicode 解析、自动 HTML escape 防止 XSS 攻击、继承、变量、过滤器、流程逻辑支持、python 代码逻辑集成等等。具体的功能和使用请参考官网的文档,这里就不介绍了。

如何读代码

阅读源代码是件耗时而又没有直接产出的事情,因此必需要事先明确目的,否则会白白浪费时间。对于我来讲,通常须要阅读源码有几个可能的缘由:

  1. 在学习语言的时候遇到瓶颈,想借鉴和学习优秀项目的风格、思路、经验等。好比在刚学习一门语言的语法以后,会发现本身仍是不能很好地使用它。这个时候,我通常会找一个项目来练手,而后阅读一些优秀项目的代码来参考它们的实现

  2. 工做中须要常常用到某个项目。好比你从事 web 开发, 常用 flask/Django 框架,熟悉它们的源码可让你在使用的时候更能驾轻就熟和有的放矢,并且遇到问题以后也能更容易去定位

  3. 本身想深刻理解某个领域的知识。对某个领域很是感兴趣,想理解它的内部实现原理,或者干脆本身想造个轮子,那么阅读源码是很好的途径

知道了本身要阅读代码,那么怎么去读代码呢?

  1. 最重要的是不要畏惧!记得我刚开始工做的时候,总以为那些项目都是很是优秀的人编写的高质量代码,本身望尘莫及,尚未深刻以前就认为本身确定看不懂,更不用去修改代码了。但其实,只要是人写的代码就会有 bug,也会有能够改进的地方,要有好的心态:欣赏好的代码设计,但也要学会识别很差的代码

  2. 不要巨细无遗!阅读代码最怕的是在细节中纠缠不清,不只拖慢进度也会大挫信心。全部的代码大概都是树形的结构,开始最重要的是理清树干的结构,知道这个树大概有几个部分,分别负责什么功能,它们之间的大概关系是啥就够了。万万不可取的是盯着某个小树叶研究半天,或者被藤蔓遮住了视线

  3. 带着问题去阅读!这个建议不只适用于代码,也适用于全部的阅读。若是在阅读以前有了明确的目的,好比想知道程序是怎么启动的、某个 bug 是何时引入的、某个功能是怎么实现的…… 带着这些问题,目的性强,理解也更快

  4. 简化再简化!若是代码的量级比较大,要学会简化问题,找到代码的核心。有几种方法:忽略细节,好比你知道某个文件夹是不一样的驱动,那么只要理解它们的接口和大体功能就行,把细节当作黑盒;运行最简单的代码,经过一个 hello world 或者 quickstart 提供的例子做为入口和理解单位;找到以前的版本,有了版本控制和网络,不少项目很容易找到历史版本,好比理解 linux 的话不少书会推荐 0.X 的版本,它的核心都在,理解也更方便

  5. 左右开弓!理解一个很大项目无外乎两种方法——从上到下和从下到上。对于比较复杂的项目,灵活使用这两种方法,从上到下容易找到脉络,但有时候由于多态或者运行时加载的缘由很难往下跟踪;从下到上掌握东西更牢固,更有针对性,但会看不清项目的全貌,不容理解总体。两种方法同时使用,直到它们出现交汇,作到融会贯通

但愿说了这么多,能对你们之后读代码和工做有点帮助。那么,从下一篇文章,咱们就正式开始 flask 源码之旅了!

相关文章
相关标签/搜索