python - flask中为何有这么多的直接返回‘一句话’调用的方法呢?
问题描述
标题可能说得不是很清楚,还是上代码:
Flask.wsgi_app(self, environ, start_response): ctx = self.request_context(environ)
然后可以看到,实际上会调用
def request_context(self, environ):return _RequestContext(self, environ)
之后再进入到class _RequestContext(object): 的__init__函数中,后面就不再写了。
我的疑惑是,在第一句生成ctx的时候,为何要弄出一个request_context 方法来呢?这个方法就只有简单的一个返回语句,那么我直接在开始的时候实例化不就好了:ctx = _RequestContext(self, environ) ? 而且像这样的使用方式在flask中其他地方也还有很多,那么这样使用有什么明显的好处吗? (或者说像我那样写的直接返回的句子有什么明显的坏处吗?)
问题解答
回答1:这是一个设计的和品位的问题,而不是一个技术问题。
就拿你举的这个例子来说,我们看到这里有一层封装,但是因为封装的内容太过于简单,所以让你疑惑是否有这个必要。要回答这个问题,我们要想想为什么会有封装?不管是函数也好,类也好,我们定义它们可能是因为以下原因:
它们提供了逻辑上的某个功能,便于我们理解
这段逻辑是会被经常调用到的,为了避免重复(DRY原则),我们把它抽象出来
这个例子是符合上面这两条的:flask 需要一个创建 application context 的功能,并且是在多处会用到它。
➜ flask grep '.request_context' -rin ../app.py:1918: with app.request_context(environ):./app.py:1925: ctx = app.request_context(environ)./app.py:1948: return self.request_context(builder.get_environ())./app.py:1977:ctx = self.request_context(environ)
另外一个好处是,RequestContext 算是比较内部的一个类,大多数情况下用户不会(也不应该)直接使用它。而为了让用户可以创建这个类的对象,作者封装了 Flask.request_context() 方法,算是最小接口原则(尽量提供最小的接口给用户)。
封装还有一个好处,只要接口固定,内部实现是可以随便更改的。你的版本里初始化是 ctx = _RequestContext(self, environ),在我安装的版本里(Flask==0.12)这行代码是 ctx = RequestContext(self, environ)。虽然这里只是一个类名的简单变化,但是通过它我们可以明白,如果我们对 RequestContext 的实现或者初始化发生了变化,所有的调用方是不用改动的;不然的话,所有的调用方都要跟着修改。
当然这里封装的内容只有一句,这些好处不是那么明显,甚至显得我有点牵强附会。但是我猜测,这是作者思考过的结果,因为 RequestContext 是 Flask 中比较重要的类,以后对它进行修改的可能性很大(增加一些属性、改变初始化的参数等),把它封装一层,可以轻松应对未来可能的变化。毕竟,软件工程一个重要的事情就是应对变化。
回答2:这就是面向对象的成员变量是否对外可见的问题了,这里操作的是类的成员变量的成员变量,不适合直接获取。可以参考一下property,你觉得property的优势在哪里?明显的就是当你所需要的属性不是直接获得而是通过计算获得的话只需要修改属性的获取方法就可以了。
相关文章:
1. docker-machine添加一个已有的docker主机问题2. angular.js - 为什么给 Angular 指令绑定事件无法生效3. html5 - 使用angular中,图片上传功能中选择多张图片是怎么实现的?有什么好的思路吗?4. golang - 用IDE看docker源码时的小问题5. docker - 各位电脑上有多少个容器啊?容器一多,自己都搞混了,咋办呢?6. 为什么我ping不通我的docker容器呢???7. MySQL 查询疑问?8. mysql 5个left关键 然后再用搜索条件 几千条数据就会卡,如何解决呢9. phpstudy 发现多个后门木马,有人遇到过吗?10. 请问一下,这是6.0的吗?为什么我下载的和老师讲的不一样呢?
