如何阅读Flask源码?
一个web项目一般都由哪些部分组成?URL映射,MVC分层,缓存,模板解析,ORM,协议等等构成了web这棵大树的主干
最近打算阅读一下Flask的源码,由于自己前读的一些代码,常是一些某个库的使用方法的代码,比如urllib2该如何使用等。而对于像框架之类的代码没有阅读过,尝试去读的时候,发现无从下手:
不知道从哪个文件开始读
对于某个模块,到底怎么个用法,不清楚该如何测试
另外,由于是Flask就是Werkzeug+Jinja2而成的,是不是有必要先从后两个开始阅读呢?
麻烦大家分享下你阅读代码的方法,是从哪里入手的,如何理解某个模块是如何实现的?
去年做过一个不大不小的Flask项目,这边分享下我的做法:
读Flask源码确实需要读Werkzeug的源码,Jinja2的源码则可以先晾在一边,原因是在框架结构上Flask与Werkzeug结合的更紧些,例如我们在一次HTTP请求上下文中使用的request实例,就是通过Werkzeug的LocalProxy包装实现的。而Jinja2则完全集中在模板渲染上,如果题主目前的主要任务是理清“HTTP请求响应流”在框架代码中的走向,那么Jinja2部分可以先作为黑匣子。
怎么切入,我认为最好的方法是在您的View Handler中用ipdb下一个断点,然后启动程序并在浏览器中访问该页面,当运行到断点时,Python进程那边已经切换到ipdb的调试模式,您可以通过步进并随时查看当前代码所处的文件、对应行数,以及当前的堆栈帧。
第一次用ipdb下断点查看时,不需要在意当前到达的每一步位置的上下文代码,只要记住我在哪个文件的哪个函数(方法)中,这样一遍走下来,您对一次HTTP请求会依次经历Flask框架中的哪些部分有个初步印象。
接下去,就是打开这些“框架部分”对应的源码文件进行宏观阅读了,这是第二步,如果有经验,能够凭直觉一眼看出(或通过方法名、或通过代码的自文档化)此处是在做什么。如果第一步用ipdb调试是在脑海中对框架打轮廓,那么第二步做完后,已经对这个框架实现有较为清晰、整体的认识了。
第三步,根据第二步所建立的认识,继续使用ipdb打断点并调试,但在这次,需要仔细地“打量”当前上下文,例如上面说的查看堆栈帧、或者通过locals()、globals()查看当前名字空间的变化,第三步的作用是为第二步所建立的概念模型进行实践验证,以加强理解
如此反复二三两步,对框架主要部分实现的认识则会愈加清晰,把握住框架主脉络后,对于其他模块,例如signals、session,则可以逐个击破了。
另外,Flask还会直接依赖itsdangerous这个库,我认为也可以了解下。
我现在还在看Flask源码,原因是它的文档字符串写得很棒,可以作为我在其他项目使用sphinx-doc组件实践时很好的模板:)。