经过werkzeug了解wsgi

Django有wsgi当作socket,而flask自身是没有wsgi的,他是经过werkzeug来实现的.flask

看源码

下面看下源码是如何实现的:app

#这是咱们写的flask代码
from
flask import Flask app = Flask(__name__) #先实例化对象 @app.route('/index') #将/index路径和index函数名作了映射(对应关系)而后放到flask里面去 def index():         return 'hello world' if __name__ == '__main__':         app.run() #从app.run()启动项目

点击(ctrl+左键,后文的点击全是这样的)run进到源码,这里的self就是app(app就是Flask实例化的对象)socket

 

 往下走,找到函数

 

点击run_simple进入到源码,这个run_simple其实就是werkzeug的代码了,进来以后,flask项目就hang住了,等待请求的进来.网站

注意,run_simple封装的内容中 hostname(主机名/IP地址),port(端口),application(函数名)是必须写的spa

 

werkzeug模拟flask

代码咱们如今只能写:3d

from werkzeug.serving import run_simple

def func(environ,start_response):       #咱们须要知道视图函数的返回值是啥,才能进一步写代码
        print('请求来了')

if __name__ == '__main__':
        run_simple('127.0.0.1',5000,func) #这里括号的内容上面源码有解释,func是个函数名,当请求来时会自动执行第三个参数+(),也就是执行func函数func(),而后就跳到上面去执行func函数了

继续看flask代码:code

from flask import Flask

app = Flask(__name__)             #先实例化对象

@app.route('/index')              #将/index路径和index函数名作了映射(对应关系)而后放到flask里面去
def index():
        return 'hello world'

if __name__ == '__main__':
        app.run()           #从app.run()启动项目

app.__call__ #由于对象+()就会执行类的__call__方法,因此咱们从Flask的__call__方法进入源码

点击call进入Flask源码对象

 

 咱们已经进入到Flask源码了,再点击wsgi_appblog

 

 其实wsgi_app就在call上面,而它的返回值response(environ, start_response)其实就是要返回给用户的,就是咱们要找的视图函数的返回值.

 

 

response就是上面2449行获得的

点full_dispatch_request进去

 

 

 这里rv我门就不深推了,他其实就是视图函数返回的字符串.

返回时对rv作了处理,咱们点finalize_request进去

 

 这里最后的response就是整个视图函数的返回值,点make_response进去

 

 

 通过一系列判断,这里最后就返回了rv,rv就是整个视图函数的返回值.

咱们须要再看下2106行对rv的判断

 

 再看下response_class

 

 

 也就是说判断一下rv是否是Response的对象,

再往下走,rv是字符串,不是Response的对象,

 

 这里就判断rv是否是字符串,rv是字符串再往下

 

 

这里你须要结合前面的过程来看:

这里就至关因而: rv = Response(rv, status=status, headers=headers),是个对象,rv是视图函数返回的字符串,须要传进去.而rv正好是make_response的返回值,而self.make_response他返回给了response.

因此response=Response(rv, status=status, headers=headers),而rv就是视图函数返回的字符串,后面的参数()status=status, headers=headers)能够不写,因此 response=Response("hello world")

rv这个字符串就被封装到rv这个Response的对象里面去了.

 

 我们再找response_class,点进去,找到Response

 

这里咱们把鼠标放到标签上,看下当前Response所在的位置(路径)

 

 此时咱们的代码能够改成:

from werkzeug.serving import run_simple
from flask.wrappers import  Response    #新加的

def func(environ,start_response):
       print("请求来了")
         response=Response("hello world")
         return response(environ,start_response)  #新加的

if __name__ == '__main__':
        run_simple('127.0.0.1',5000,func)

可是仍是有点不严谨,由于你引用的模块是flask的,咱们前面说了,werkzeug不须要flask,而是werkzeug为flask提供socket功能.

由于Response继承了ResponseBase,因此点进去看

 

 这里,咱们看到了在werkzzeug下的Response继承了BaseResponse,

 

 咱们再向上看,上面的import已经把BaseResponse给引过来了

 

 因此咱们能够在原来的代码上写from werkzeug.wrappers import  BaseResponse,或者咱们再点进 BaseResponse看他从哪来

 

 咱们看下wrappers的init文件写啥:

 

这里是吧BaseResponse引到wrappers文件的init文件中了,你只要引入wrappers文件就能够倒入BaseResponse这个类了

因此from werkzeug.wrappers.response import BaseResponse 或者是from werkzeug.wrappers.base_response import BaseResponse

再或者from werkzeug.wrappers import BaseResponse均可以引入BaseResponse这个类

from werkzeug.serving import run_simple
from werkzeug.wrappers import  BaseResponse

def func(environ,start_response):
       print("请求来了")
         response=BaseResponse("你好")
         return response(environ,start_response)

if __name__ == '__main__':
        run_simple('127.0.0.1',5000,func)

因此我们能够不依赖flask只用werkzeug也能够实现搭建网站的功能.

相关文章
相关标签/搜索