欧美亚洲中文,在线国自产视频,欧洲一区在线观看视频,亚洲综合中文字幕在线观看

      1. <dfn id="rfwes"></dfn>
          <object id="rfwes"></object>
        1. 站長(zhǎng)資訊網(wǎng)
          最全最豐富的資訊網(wǎng)站

          Python學(xué)習(xí)之解析Flask運(yùn)行原理(圖文詳解)

          本篇文章給大家?guī)砹岁P(guān)于python的相關(guān)知識(shí),其中主要介紹了Flask的運(yùn)行原理相關(guān)問題,對(duì)Flask的運(yùn)行原理做一簡(jiǎn)要解析,以增強(qiáng)對(duì)Flask的了解,希望對(duì)大家有幫助。

          Python學(xué)習(xí)之解析Flask運(yùn)行原理(圖文詳解)

          推薦學(xué)習(xí):python學(xué)習(xí)教程

          ??所有的 Python Web框架都要遵循 WSGI 協(xié)議,在這里還是要簡(jiǎn)單回顧一下 WSGI 的核心概念。

          ??WSGI 中有一個(gè)非常重要的概念:每個(gè)Python Web應(yīng)用都是一個(gè)可調(diào)用(callable)的對(duì)象。在 flask 中,這個(gè)對(duì)象就是 app = Flask(name) 創(chuàng)建出來的 app,就是下圖中的綠色Application部分。要運(yùn)行web應(yīng)用,必須有 web server,比如我們熟悉的apache、nginx,或者python中的gunicorn,我們下面要講到的werkzeug提供的WSGIServer,它們是下圖的黃色Server部分。
          Python學(xué)習(xí)之解析Flask運(yùn)行原理(圖文詳解)
          ??Server和Application之間怎么通信,就是WSGI的功能。它規(guī)定了 app(environ, start_response) 的接口,server會(huì)調(diào)用 application,并傳給它兩個(gè)參數(shù):environ 包含了請(qǐng)求的所有信息,start_response 是 application 處理完之后需要調(diào)用的函數(shù),參數(shù)是狀態(tài)碼、響應(yīng)頭部還有錯(cuò)誤信息。

          ??WSGI application 非常重要的特點(diǎn)是:它是可以嵌套的。換句話說,可以寫個(gè)application,它做的事情就是調(diào)用另外一個(gè) application,然后再返回(類似一個(gè) proxy)。一般來說,嵌套的最后一層是業(yè)務(wù)應(yīng)用,中間就是 middleware。這樣的好處是,可以解耦業(yè)務(wù)邏輯和其他功能,比如限流、認(rèn)證、序列化等都實(shí)現(xiàn)成不同的中間層,不同的中間層和業(yè)務(wù)邏輯是不相關(guān)的,可以獨(dú)立維護(hù);而且用戶也可以動(dòng)態(tài)地組合不同的中間層來滿足不同的需求。
          Python學(xué)習(xí)之解析Flask運(yùn)行原理(圖文詳解)
          ??Flask基于Werkzeug WSGI工具箱和Jinja2 模板引擎。 Flask使用BSD授權(quán)。 Flask也被稱為“microframework”,因?yàn)樗褂煤?jiǎn)單的核心,用extension增加其他功能。Flask沒有默認(rèn)使用的數(shù)據(jù)庫、窗體驗(yàn)證工具。然而,F(xiàn)lask保留了擴(kuò)增的彈性,可以用Flask-extension加入這些功能:ORM、窗體驗(yàn)證工具、文件上傳、各種開放式身份驗(yàn)證技術(shù)。我們可以這么理解,F(xiàn)lask是一個(gè)核心,而其他功能則是一些插件,需要什么功能,只要找到對(duì)應(yīng)的插件,將其插入核心就能夠?qū)崿F(xiàn)該功能了。

          ??Flask是怎么將代碼轉(zhuǎn)換為我們可見的Web網(wǎng)頁的。首先,我們得先從Web程序的一般流程來看,對(duì)于我們的Web應(yīng)用來說,當(dāng)客戶端想要獲取動(dòng)態(tài)資源 時(shí),(比如ASP和PHP這類語言寫的網(wǎng)站),這個(gè)時(shí)候就會(huì)發(fā)起一個(gè)HTTP請(qǐng)求(比如用瀏覽器訪問一個(gè)URL),此時(shí)Web應(yīng)用程序就會(huì)在服務(wù)器后臺(tái)進(jìn)行相應(yīng)的業(yè)務(wù)處理(比如對(duì)數(shù)據(jù)庫進(jìn)行操作或是進(jìn)行一些計(jì)算操作等),取出用戶需要的數(shù)據(jù),生成相應(yīng)的HTTP響應(yīng)(當(dāng)然,如果訪問的是 靜態(tài)資源 ,服務(wù)器則會(huì)直接返回用戶所需的資源,不會(huì)進(jìn)行業(yè)務(wù)處理)。整個(gè)處理工程如下所示:
          Python學(xué)習(xí)之解析Flask運(yùn)行原理(圖文詳解)
          ??在實(shí)際的應(yīng)用中,不同的請(qǐng)求可能會(huì)調(diào)用相同的處理邏輯。這里有著相同業(yè)務(wù)處理邏輯的HTTP請(qǐng)求可以用一類URL來標(biāo)識(shí)。比如在我們的博客站點(diǎn)中,對(duì)于所有想要獲取Articles內(nèi)容的請(qǐng)求而言,可以用 articles/這類URL來表示,這里的article_id用以區(qū)分不同的article。接著在后臺(tái)定義一個(gè)get_article(article_id)的函數(shù),用來獲取article相應(yīng)的數(shù)據(jù),此外還需要建立URL和函數(shù)之間的一一對(duì)應(yīng)關(guān)系。這就是Web開發(fā)中所謂的路由分發(fā) ,如下圖所示:
          Python學(xué)習(xí)之解析Flask運(yùn)行原理(圖文詳解)
          ??在Flask中,使用werkzeug來做路由分發(fā),werkzeug是Flask使用的底層WSGI庫(WSGI,全稱 Web Server Gateway interface,或者 Python Web Server Gateway Interface,是為 Python 語言定義的Web服務(wù)器和Web應(yīng)用程序之間的一種簡(jiǎn)單而通用的接口)。
          ??WSGI將Web服務(wù)分成兩個(gè)部分:服務(wù)器和應(yīng)用程序。WGSI服務(wù)器只負(fù)責(zé)與網(wǎng)絡(luò)相關(guān)的兩件事:接收瀏覽器的HTTP請(qǐng)求、向?yàn)g覽器發(fā)送HTTP應(yīng)答;而對(duì)HTTP請(qǐng)求的具體處理邏輯,則通過調(diào)用WSGI應(yīng)用程序進(jìn)行。WSGI工作流程如下圖所示:
          Python學(xué)習(xí)之解析Flask運(yùn)行原理(圖文詳解)
          ??在Flask中,路由分發(fā)的代碼寫起來十分簡(jiǎn)單,如下:

          # 管理員注銷頁面 @main.route('/logout') def logout():     dm = DataManager()     currentUsers = dm.getUsers('0')     print(currentUsers[0])     return render_template('currentUsers.html', users=currentUsers)

          ??通過業(yè)務(wù)邏輯函數(shù)獲得我們所需的數(shù)據(jù)后,服務(wù)器將會(huì)根據(jù)這些數(shù)據(jù)來生成HTTP響應(yīng)(對(duì)于Web應(yīng)用來說,一般就是一個(gè)HTML文件,這個(gè)是可以直接被我們的客戶端,即瀏覽器直接讀取并解釋的)。在Web開發(fā)中,常規(guī)的做法是將獲取的數(shù)據(jù)傳入Web應(yīng)用提供的一個(gè)HTML模板文件中,經(jīng)過模板系統(tǒng)的渲染后最終得到我們所需要的HTML響應(yīng)文件。
          ??一般情況下,雖然請(qǐng)求不同,但是響應(yīng)中的數(shù)據(jù)的展示方式是相同的 ,通俗點(diǎn)說就是除了我們請(qǐng)求獲得的數(shù)據(jù)不一樣外,其他都是一樣的,那么我們就可以設(shè)計(jì)一個(gè)模板(除了數(shù)據(jù)內(nèi)容可以改動(dòng),其他都是固定的HTML文件)。我們以博客站點(diǎn)為例,對(duì)不同article而言,其具體article content雖然不同,但頁面展示的內(nèi)容除了請(qǐng)求的數(shù)據(jù)外都是一樣的,都有標(biāo)題攔,內(nèi)容欄等。也就是說,對(duì)于article來說,我們只需提供一個(gè)HTML模板,然后傳入不同article數(shù)據(jù),即可得到不同的HTTP響應(yīng)。這就是所謂的模板渲染 ,如下圖所示:
          Python學(xué)習(xí)之解析Flask運(yùn)行原理(圖文詳解)
          ??在Flask中使用Jinja2模板渲染引擎來做模板渲染(Jinja2是基于python的模板引擎,功能比較類似于于PHP的smarty,J2ee的Freemarker和velocity。它能完全支持unicode,并具有集成的沙箱執(zhí)行環(huán)境,應(yīng)用廣泛。jinja2使用BSD授權(quán))。Jinja2的工作流程如下圖所示:
          Python學(xué)習(xí)之解析Flask運(yùn)行原理(圖文詳解)
          ??在Flask中,模板渲染的代碼寫起來也是十分的便捷,代碼如下:

          @app.route('/articles/<int:article_id>/')  defget_article(article_id): returnrender_template('path/to/template.html', data_needed)

          ??在Flask中,我們處理一個(gè)請(qǐng)求的流程就是,首先根據(jù)用戶提交的URL來決定由哪個(gè)業(yè)務(wù)邏輯函數(shù)來處理,然后在函數(shù)中進(jìn)行操作,取得所需的數(shù)據(jù)。再將取得的數(shù)據(jù)傳給相應(yīng)的模板文件中,由Jinja2負(fù)責(zé)渲染得到HTTP響應(yīng)內(nèi)容,即HTTP響應(yīng)的HTML文件,然后由Flask返回響應(yīng)內(nèi)容。
          ??下面主要以實(shí)例項(xiàng)目對(duì)Flask運(yùn)行原理做一簡(jiǎn)要解析。在實(shí)例項(xiàng)目中,使用到了程序工廠函數(shù)和藍(lán)本。項(xiàng)目目錄結(jié)構(gòu)如下:
          Python學(xué)習(xí)之解析Flask運(yùn)行原理(圖文詳解)
          ??在manager.py文件中,定義了項(xiàng)目啟動(dòng)的入口函數(shù):

          # 確保服務(wù)器只會(huì)在該腳本被 Python 解釋器直接執(zhí)行的時(shí)候才會(huì)運(yùn)行,而不是作為模塊導(dǎo)入的時(shí)候。 if __name__ == '__main__':     # 啟用cmd命令行     # manager.run()     app.run(host='0.0.0.0', port=9000, debug=True)

          同時(shí),在該文件中創(chuàng)建了工廠方法實(shí)例:

          	app = create_app()

          ??在工程方法中,對(duì)數(shù)據(jù)庫進(jìn)行了相關(guān)配置,創(chuàng)建了前端導(dǎo)航欄,同時(shí)對(duì)所創(chuàng)建的藍(lán)本進(jìn)行了注冊(cè)。在創(chuàng)建的藍(lán)本中主要涉及授權(quán)、路由及錯(cuò)誤處理模塊。

          # 構(gòu)造工廠方法 def create_app():     # 在這里__name__ == __main__     app = Flask(__name__)     app.url_map.converters['regex'] = RegexConverter     # 防止跨站攻擊 注:為了增強(qiáng)安全性,密鑰不應(yīng)直接寫入代碼,而應(yīng)該保存在環(huán)境變量中     # app.config['SECRET_KEY'] = 'hard to guess string SUNNY2017'     # app.secret_key = 'Sunny123456'      # flask提供的讀取外部文件     app.config.from_pyfile('config')      # basedir = os.path.abspath(os.path.dirname(__file__))     # print(basedir)      # 配置數(shù)據(jù)庫連接     app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://lmapp:lmapp@localhost/smp'     app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True     app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True      nav.register_element('top', Navbar(u'APP安盾',                                        View(u'當(dāng)前在線', 'main.index'),                                        View(u'全部用戶', 'main.all_users'),                                        View(u'注銷', 'main.logout'),                                        View(u'修改密碼', 'main.chgpwd'),                                        ))     nav.init_app(app)     db.init_app(app)     bootstrap.init_app(app)     # init_views(app)     from .auth import auth as auth_blueprint     from .main import main as main_blueprint     # 注冊(cè)藍(lán)本 url_prefix='/auth'     app.register_blueprint(auth_blueprint,)     app.register_blueprint(main_blueprint, static_folder='static')     return app

          推薦學(xué)習(xí):python教程

          贊(0)
          分享到: 更多 (0)
          網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)