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
代碼咱們如今只能寫: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也能夠實現搭建網站的功能.