摘要:官方示例第一行類對象,這個無需解釋。請求對象的端點(diǎn)請求視圖函數(shù)的參數(shù)通過源碼的注釋我們可以知道,都只是對庫的進(jìn)行了一層包裝并加入一些屬性。接下來會有更多關(guān)于和相關(guān)文章放出來,敬請期待參考文檔項目源碼版本注釋版
Flask 是一個 Python 實(shí)現(xiàn)的 Web 開發(fā)微框架, 有豐富的生態(tài)資源。本文從一段官方的示例代碼通過一步步打斷點(diǎn)方式解釋 Flask 內(nèi)部的運(yùn)行機(jī)制,在一些關(guān)鍵概念會有相關(guān)解釋,這些前提概念對整體理解 Flask框架十分重要,本文基于flask 0.1 版本進(jìn)行相應(yīng)的分析。
from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): return "Hello World!" if __name__ == "__main__": app.run()
第一行import Flask 類對象,這個無需解釋。跳到第二行,使用當(dāng)前模塊的名字傳入Flask類中,并實(shí)例化Flask對象,我們在這個地方打個斷點(diǎn),看看Flask類別里有什么。
上圖可以看出,F(xiàn)lask類中定義jinia_options、request_class、response_class等屬性,這里我們不關(guān)系具體作用,先看看源碼中Flask 是不是定義了這些屬性。
class Flask(object): # 省略了注釋部分 # flask 用作請求對象的類 request_class = Request # flask 用作響應(yīng)對象的類 response_class = Response # 靜態(tài)文件路徑 static_path = "/static" # 密鑰,用于加密 session 或其它涉及安全的東西 secret_key = None #存儲session對象數(shù)據(jù)的cookie名稱 session_cookie_name = "session" # Jinja2環(huán)境的一些選項 jinja_options = dict( autoescape=True, extensions=["jinja2.ext.autoescape", "jinja2.ext.with_"] )
這部分是初始化Flask類中默認(rèn)設(shè)置的一些屬性,其實(shí)通過名字也可以大概知道每個屬性的作用。看到這個地方時是不是一臉懵逼,Request、Response 是什么東西,有什么作用?Jinja2 又是什么東西? 別急,下面慢慢解釋這幾個東西的作用。
Request && Responsefrom werkzeug import Request as RequestBase, Response as ResponseBase class Request(RequestBase): """The request object used by default in flask. Remembers the matched endpoint and view arguments. It is what ends up as :class:`~flask.request`. If you want to replace the request object used you can subclass this and set :attr:`~flask.Flask.request_class` to your subclass. """ def __init__(self, environ): RequestBase.__init__(self, environ) self.endpoint = None # 請求對象的端點(diǎn) self.view_args = None # 請求視圖函數(shù)的參數(shù) class Response(ResponseBase): """The response object that is used by default in flask. Works like the response object from Werkzeug but is set to have a HTML mimetype by default. Quite often you don"t have to create this object yourself because :meth:`~flask.Flask.make_response` will take care of that for you. If you want to replace the response object used you can subclass this and set :attr:`~flask.Flask.request_class` to your subclass. """ default_mimetype = "text/html"
通過源碼的注釋我們可以知道,Request、Response都只是對 werkzeug 庫的Request、Response 進(jìn)行了一層包裝并加入一些屬性。先說一下它們的作用:
Request 的作用:是 flask 默認(rèn)的請求對象,用來記住匹配的endpoint(端點(diǎn))和view arguments(視圖參數(shù))
Response 的作用:是 flask 默認(rèn)的響應(yīng)對象,默認(rèn)設(shè)置MIME類型默認(rèn)設(shè)置為HTML(即是定義了內(nèi)容類型 Content-Type 返回的類型為HTML), 默認(rèn)情況下,你不用自己創(chuàng)建這個對象,因為下面的 make_response 函數(shù)會幫你處理。
看完上面源碼和解釋,是不是有新的疑問了,werkzeug又是什么?端點(diǎn)又是什么概念?額,werkzeug的作用真的很大,整個框架都是基于它實(shí)現(xiàn)的,下面會有一個部分專門說明這個庫。說明: werkzeug 庫和 jinja2 是 flask 的兩個依賴庫,會分出一篇文章專門介紹,這篇文章重點(diǎn)是整個 Flask 內(nèi)部的機(jī)制,建議看到對應(yīng)部分,先提前去讀兩個依賴庫的文章。
接下來繼續(xù)下一步的調(diào)試,初始化一個Flask類, 先看看 Flask 類的初始化函數(shù):
def _get_package_path(name): """Returns the path to a package or cwd if that cannot be found.""" # 獲取 模塊包 路徑,被 Flask 引用 try: return os.path.abspath(os.path.dirname(sys.modules[name].__file__)) except (KeyError, AttributeError): return os.getcwd() class Flask(object): # 簡化版,已經(jīng)去掉注釋,建議看源碼注釋加上這個理解 def __init__(self, package_name): # 設(shè)置是否開啟調(diào)試模式,若開啟,會監(jiān)視項目代碼變化, # 開發(fā)服務(wù)器重載 Flask 應(yīng)用 self.debug = False # 包或模塊的名字,模塊的名稱將會因其作為多帶帶應(yīng)用啟動還是作為模塊導(dǎo)入而不同 # Flask 才知道到哪去找模板、靜態(tài)文件 self.package_name = package_name # 根據(jù) Flask 傳入的__name__, 找到項目的根路徑 self.root_path = _get_package_path(self.package_name) # 已注冊的所有視圖函數(shù)的字典,字典的鍵是函數(shù)名稱,可以用來生成URL(url_for函數(shù)) # 字典的值是函數(shù)本身, 想要注冊視圖函數(shù),可以使用 route 裝飾器 self.view_functions = {} # 所有已注冊錯誤處理程序的字典, 字典的鍵是一個整數(shù)類型(integer)的錯誤碼 # 字典的值是對應(yīng)錯誤的函數(shù),想要注冊錯誤handler, 可以使用 errorhandler 裝飾器 self.error_handlers = {} # 請求開始進(jìn)入時,但還請求還沒調(diào)度前調(diào)用的函數(shù)列表,也就是預(yù)處理操作 # 可用于打開數(shù)據(jù)庫連接或獲取當(dāng)前登錄用戶,使用 before_route 裝飾器注冊 self.before_request_funcs = [] # 請求結(jié)束時調(diào)用的函數(shù)列表,這些函數(shù)會被傳入當(dāng)前響應(yīng)對象并將其修改或替換它。 self.after_request_funcs = [] # 不帶參數(shù)調(diào)用的函數(shù)列表,用于填充模板上下文,每個應(yīng)該返回更新模板上下文的字典 # 默認(rèn)的處理器用來注入session、request和g self.template_context_processors = [_default_template_ctx_processor] # 使用 werkzeug 的 routing.Map, 用于給應(yīng)用增加一些URL規(guī)則, # URL規(guī)則形成一個Map實(shí)例的過程中會生成對應(yīng)的正則表達(dá)式,可以進(jìn)行URL匹配 self.url_map = Map() # 添加靜態(tài)文件的URL映射規(guī)則 # SharedDataMiddleware中間件用來為程序添加處理靜態(tài)文件的能力 if self.static_path is not None: self.url_map.add(Rule(self.static_path + "/", build_only=True, endpoint="static")) if pkg_resources is not None: target = (self.package_name, "static") else: target = os.path.join(self.root_path, "static") self.wsgi_app = SharedDataMiddleware(self.wsgi_app, { self.static_path: target # URL路徑和實(shí)際文件目錄(static文件夾)的映射 }) # Jinja2 環(huán)境,它通過jinja_options創(chuàng)建,加載器(loader)通過 self.jinja_env = Environment(loader=self.create_jinja_loader(), **self.jinja_options) # 將url_for, get_flashed_message 作為全局對象填充入模板上下文中,可以在模板中調(diào)用它們 self.jinja_env.globals.update( url_for=url_for, get_flashed_messages=get_flashed_messages )
上面就是一個 Flask 實(shí)例化時所做的工作,其實(shí)就是保存了一下配置信息,設(shè)置了一下Jinja2 環(huán)境,并定義了一個URL 映射對象,用于映射URL 到函數(shù)之間的關(guān)系。
總結(jié)開篇主要講了初始化一個Flask對象,內(nèi)部做了什么工作,配置了一下信息,設(shè)置了一下Jinja2 環(huán)境,定義了一些視圖函數(shù)存放的數(shù)據(jù)結(jié)構(gòu),定義了一個Map對象用于后面保存URL 和 視圖函數(shù)的映射關(guān)系。接下來會有更多關(guān)于werkzeug, jinja2 和 WSGI 相關(guān)文章放出來,敬請期待!?。?/p> 參考
flask文檔
flask項目源碼0.1版本
flask注釋版
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/42492.html
摘要:月份發(fā)布了第版,收到不少網(wǎng)友的良好建議,所以又抽空進(jìn)行了完善,當(dāng)然也拖了不少時間。本書主要介紹的基本使用,這也是我一開始在學(xué)習(xí)過程中經(jīng)常用到的。第章實(shí)戰(zhàn),介紹了如何開發(fā)一個簡單的應(yīng)用。聲明本書由編寫,采用協(xié)議發(fā)布。 showImg(https://segmentfault.com/img/remote/1460000007484050?w=200&h=152); 書籍地址 head-f...
摘要:測試驅(qū)動開發(fā)簡稱,是一種軟件開發(fā)過程中的應(yīng)用方法,,由極限編程中倡導(dǎo),以其倡導(dǎo)先寫測試程序,然后編碼實(shí)現(xiàn)其功能得名。測試驅(qū)動著整個開發(fā)過程首先,驅(qū)動代碼的設(shè)計和功能的實(shí)現(xiàn)其后,驅(qū)動代碼的再設(shè)計和重構(gòu)。 showImg(https://segmentfault.com/img/remote/1460000017081716); 前言 一直都有聽到 TDD 測試驅(qū)動開發(fā)的開發(fā)方式,之前看...
摘要:簡介官網(wǎng)上對它的定位是一個微開發(fā)框架。另外一個必須理解的概念是,簡單來說就是一套和框架應(yīng)用之間的協(xié)議。功能比較豐富,支持解析自動防止攻擊繼承變量過濾器流程邏輯支持代碼邏輯集成等等。那么,從下一篇文章,我們就正式開始源碼之旅了 文章屬于作者原創(chuàng),原文發(fā)布在個人博客。 flask 簡介 Flask 官網(wǎng)上對它的定位是一個微 python web 開發(fā)框架。 Flask is a micro...
摘要:獲取成為開發(fā)專家的技巧。我們可以在兩個文本框輸入筆記的標(biāo)題和內(nèi)容。在本教程中,我們將使用一個名為的工具。它是一個火狐瀏覽器的擴(kuò)展,我們可以使用它管理數(shù)據(jù)庫。安裝,打開火狐瀏覽器,點(diǎn)擊,然后點(diǎn)找到的文件夾圖標(biāo)并點(diǎn)擊它。 showImg(https://cdn-images-1.medium.com/max/600/1*Ou6FFJJD3zhcIUU8wBZqIw.png); 教程譯文首發(fā)...
摘要:作為網(wǎng)站的基礎(chǔ)框架,于年月日發(fā)布,目前已經(jīng)獲得了很多社區(qū)的支持,并且在一系列不同的場景種得到應(yīng)用。使用該框架,開發(fā)者能夠快速開發(fā)出即安全又強(qiáng)大的用戶身份認(rèn)證機(jī)制,例如機(jī)制用戶身份認(rèn)證防止跨站攻擊等等。 下一篇文章:Python:Tornado 第一章:異步及協(xié)程基礎(chǔ):第一節(jié):同步與異步I/O Tornado是一個可擴(kuò)展的非阻塞Web服務(wù)器以及相關(guān)工具的總稱。Tornado每秒可以處理...
閱讀 3695·2021-10-09 09:44
閱讀 3400·2021-09-22 15:29
閱讀 3158·2019-08-30 15:54
閱讀 3030·2019-08-29 16:19
閱讀 2157·2019-08-29 12:50
閱讀 602·2019-08-26 14:04
閱讀 1709·2019-08-23 18:39
閱讀 1359·2019-08-23 17:59