通过werkzeug了解wsgi
Django有wsgi当做socket,而flask自身是没有wsgi的,他是通过werkzeug来实现的.
看源码
下面看下源码是如何实现的:
#这是我们写的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实例化的对象)
往下走,找到
点击run_simple进入到源码,这个run_simple其实就是werkzeug的代码了,进来之后,flask项目就hang住了,等待请求的进来.
注意,run_simple封装的内容中 hostname(主机名/IP地址),port(端口),application(函数名)是必须写的
werkzeug模拟flask
代码我们现在只能写:
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代码:
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_app
其实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也可以实现搭建网站的功能.
最新文章
- iOS--高级技术
- 确定比赛名次---HDU1285(拓扑排序)
- vuejs切换视图同时保持状态
- ol,ul,dl,table标签的基本语法
- 如何设置DNS的SPF记录
- POJ 2406 Power Strings KMP运用题解
- PB中用回车键实现tab键的功能
- Webform Lable
- 从response.header中提取cookie,在request里添加cookie
- js中的3种弹出式消息提醒(警告窗口,确认窗口,信息输入窗口)的命令式
- composer在update时提示file could not be downloaded: SSL operation failed with code 1. OpenSSL Error messages: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO
- PAT A1141 PAT Ranking of Institutions (25 分)——排序,结构体初始化
- __ATTRIBUTE__ 知多少?
- Morris图表使用小记
- Kettle 连接 Oracle 问题总结
- Js与正则表达式
- Docker镜像保存save、加载load
- HDU1312 Red and Black(DFS) 2016-07-24 13:49 64人阅读 评论(0) 收藏
- 使用C语言调用mysql数据库编程实战以及技巧
- CSS节选——选择器