到底怎么才算“懂”python的twisted框架?

从众多互联网技术的招聘中,特别是像前端招聘等,我们可以经常找到如此字样——“熟练掌握xxx框架”,比如php的TP,python的Django,Flask等(python简直太多了),js的vue,react等,nodejs的express,java的Spring等等,五花八门,眼花缭乱。更有趣的是,似乎很多时候c++工程师招聘上写的是“熟练掌握c++”而不是“熟练掌握xxx框架”(熟练是一个比较柔和的词,毕竟c++之父都不敢说自己精通c++)。

那么问题来了,怎么才算“懂”一个框架?

——“知道怎么用,能用来开发

这个是一个很直接,粗暴的回答,可以说完全正确,因为这是一个结果导向的方法,也符合“实践是检验真理的唯一标准”的哲学理念。但是,这更像是一个很好“局外人”的完美回答。作为一个“当局者”,这多多少少会让人觉得没劲——这不是废话吗——的确,对于开发者来说,可能需要一个更好的回答,一个带有指导性的回答。我们常说“世界观决定方法论”,首先你得能“决定”方法论啊,否则不就是废话吗?

很不幸,也很幸运,笔者就曾经被包括Jquery,thinkphp,CI,Flask,express,Twisted等等“蹂躏”,“折磨”,按道理说,人不能在一个地方跌倒两次,我这都跌倒无数次了,到底是为何?我想我需要反思一下这后面反映的错误的“世界观”。我开始想——到底怎么才算“懂”python的twisted框架?

首先思考一个问题——写框架的人是怎么写出框架的?同样是写代码,为何你这么秀?

我们知道,代码是为了解决问题存在而不是为了制造问题。那很自然而言,“懂”一个框架,意味着知道一个框架是为了解决什么问题。这是一个很庞大的问题,但是这无可避免,因为每一个框架都是对问题抽象到了一定程度的结果。比如,Twisted是一个面向多任务的程序框架,即如何构建一个并发处理多个任务的程序。这是一个具有普遍意义的问题,解决方案无非几种

1、单线程编程,只用一个线程处理一个或多个任务

2、多线程编程,每一个线程处理一个或多个任务

而以上又可以分为同步编程和异步编程,同步就是说只有当一个任务完成了,才能开始下一个任务,但是这就有一个问题,当该任务因为某种原因阻塞了,那么此时的cpu是空闲了,它在等待阻塞态重新编程运行态然后执行,这导致的结果是资源被浪费了。那么Twisted是怎么做的呢,它用的是单线程异步编程,也就是说,当一个任务阻塞时,它是不会等待,而是去执行其他任务。ok,想法很简单,那么应该如何实现呢?

Twisted框架的建模

因为是单线程异步,一个很自然而然的想法是,用一个循环来驱动任务处理——reactor模型,只有当特定的事件发生,才会触发每个任务的执行(比如阻塞态变成运行态)。

那么接下来的问题是当event来了,应该如何触发任务的执行?很简单,这里Twisted用的是回调。(想象一个你给一间学校提交的申请,接下来只需要等待通知就好了,因为简历中填写了你的联系方式,这就是现实生活中的回调)

That is it

这就是Twisted的运行模型。很简单是不是,但是知道和实现是两回事,中间隔着万水千山。不然为何说“懂得了很多道理,仍然过不好这一生”?我们继续往下看

现在我们知道Twisted是想解决的问题了,也知道了他的模型是怎样的,ok,那么框架是要做什么呢?或者说在一个确定性的问题(模型出来代表着伪代码也就出来了)面前,有哪些是需要框架来做的?

首先,写框架的人都是“为人民服务”的,他们的工作就是,让面对同样问题的人只需要付出最少的劳动就可以得到解决方案。换句话说就是,写框架就是从这个模型中,抽象出最基本的通用功能

比如说,Reactor Loop是都需要的,而且在不同的场景下无差别。那就将Reactor Loop的管理抽象出来吧。其次是回调的管理,这里需要解决两个问题

1、不同的回调处理的的问题是不一样的,但是将回调注册到Reactor Loop中这个行为应该是一样的(就比如,大家都是通过在简历中写自己的邮箱,电话号码来实现回调),那么这个注册回调的功能也是需要抽象处理来的

2、回调本身是一个复杂的机制,因为如果在回调中出现问题,那么Reactor Loop应该如何处理,所以第二个问题是如何将回调本身抽象出来,使得用户可以将更多的精力放在回调函数中可预测部分,至于可能出现的异常部分,这个是普遍存在的,需要抽象出相应的解决方案

Twisted对应的解决方案:

首先用一个Application类来解决Reactor Loop的管理,用户只需要引入该类并声明即可。至于上述两个问题solution如下:

1、使用一个service类,即框架用户只需要在service中定义自己的业务逻辑,然后调用该service的注册函数,将该service注册到Application中(即让Reactor来不断的遍历看有哪些任务是可以运行的)

2、使用一个defferred类来管理回调,该类对象可以帮助用户处理异常问题。(当然也可以用python中的generator实现,这里只是另外一个比较优雅的solution而已)

以上,就是Twisted程序本身的内容,它解决的问题是“如何实现一个能够同时处理多任务的程序”。

完了吗?NOT ENOUGH!!!

还有一个很重要的问题,那就是Twisted程序的启动和部署。也就是说,一个框架,除了要完成它本身要完成的任务,还要完成它的解决方案带来的问题!(天下没有免费的午餐!),换言之,你用编程语言来解决问题,那么你就要让这段程序在不同的环境中能够按照你希望的方式来启动!

好,那来分解一下这个问题,所谓的部署和启动指的是什么?

1、程序的依赖包以及资源文件的管理。

2、启动的参数。

其实无论什么框架(其实是无论用不用框架,这都是应该思考和解决的问题,只是框架提供了一种比较优雅的方法),都要回答这两个问题,解决方案当然是各种各样。比如在Twisted中就是用python的一个包管理工具setuptools来完成。而用户只需要定义一个setup.py文件即可。至于setuptools的具体功能和用法,这些都是单纯针对python程序的部署和启动这个问题的解决方案。

Bravo!

好了吗?还差点,再思考一个问题,如果你写好的python程序需要作为第三方给别人用,应该如何做呢?

还好,setuptools帮我们解决了这个问题,具体的方法无非是告诉setuptools你的程序的依赖项和需要被引入的部分是什么,这中间当然会有各种各种的问题,但是以问题导向的思考倒是一个好方法。

Finally,我觉得可以说“懂”这个框架了。但是,“懂”和“会”之间依旧差着十万八千里!!!但起码,对于这个框架的使用和调试是有方法论了!

总结:

1、以问题为导向去学习一个框架

2、单纯从过程中的问题的解决方案看,门门都是学问,思考这些问题和解决方案是触类旁通的关键。

etc.

------------------------------------------------------------------------------------------------------------------------------

转载请注明出处https://blog.csdn.net/ganzr/article/details/87809084

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页