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