最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Flask中特殊裝飾器的使用

 更新時間:2023年12月22日 09:18:51   作者:孤寒者  
在Flask中,before_request和after_request是用作裝飾器的特殊函數(shù),本文主要介紹了Flask中特殊裝飾器的使用,具有一定的參考價值,感興趣的可以了解一下

Flask中用作裝飾器的特殊的函數(shù) 第一部分:before_request和after_request

在Flask中,before_requestafter_request是用作裝飾器的特殊函數(shù),它們可以用來在請求處理過程中執(zhí)行某些操作。

一、 before_request裝飾器:

  • 通過在函數(shù)上使用@app.before_request裝飾器,可以將該函數(shù)注冊為全局的請求前鉤子(hook)。這意味著每次請求到達(dá)服務(wù)器時,在實際處理請求之前,都會先執(zhí)行被before_request裝飾的函數(shù)。
  • before_request函數(shù)通常用于執(zhí)行一些預(yù)處理任務(wù),例如驗證用戶身份、設(shè)置全局變量、打開數(shù)據(jù)庫連接等。它可以修改請求或應(yīng)用程序上下文,并且可以返回響應(yīng)對象或 None(后面扒扒源碼看看)。

比如:

@app.before_request
def before_request():
    # 執(zhí)行一些預(yù)處理任務(wù)
    if not current_user.is_authenticated:
        return redirect(url_for('login'))

二、after_request裝飾器:

  • 通過在函數(shù)上使用@app.after_request裝飾器,可以將該函數(shù)注冊為全局的請求后鉤子。這意味著在每次請求完成并返回響應(yīng)之后,都會執(zhí)行被after_request裝飾的函數(shù)。
  • after_request函數(shù)通常用于執(zhí)行一些后處理任務(wù),例如**添加響應(yīng)頭、記錄請求日志、關(guān)閉數(shù)據(jù)庫連接等。**它接收一個參數(shù),即響應(yīng)對象,并且必須返回一個響應(yīng)對象。

比如:

@app.after_request
def after_request(response):
    # 執(zhí)行一些后處理任務(wù)
    response.headers['X-Frame-Options'] = 'SAMEORIGIN'
    return response

通過使用before_requestafter_request裝飾器,可以在請求的前后執(zhí)行一些共同的邏輯,從而實現(xiàn)全局的預(yù)處理和后處理操作。這樣可以避免在每個視圖函數(shù)中重復(fù)編寫相同的代碼。

三、多個before_request和after_request執(zhí)行流程分析:

首先—理論講解:

當(dāng)存在多個before_requestafter_request裝飾器時,分析它們的執(zhí)行順序:

before_request執(zhí)行流程:

  • 當(dāng)一個請求到達(dá)服務(wù)器時,首先會執(zhí)行第一個注冊before_request裝飾的函數(shù)。
  • 如果該函數(shù)返回了一個響應(yīng)對象,則停止執(zhí)行后續(xù)所有的before_request函數(shù),而是直接返回該響應(yīng)對象給客戶端。
  • 如果該函數(shù)沒有返回響應(yīng)對象,則繼續(xù)執(zhí)行下一個注冊的before_request函數(shù),以此類推,直到所有的before_request函數(shù)都被執(zhí)行完畢。

after_request執(zhí)行流程:

  • 在每次請求完成并返回響應(yīng)之后,從最后一個注冊after_request裝飾的函數(shù)開始執(zhí)行。
  • 每個after_request函數(shù)都會接收前一個after_request函數(shù)所返回的響應(yīng)對象作為參數(shù),并且必須返回一個新的響應(yīng)對象。
  • 執(zhí)行完最后一個after_request函數(shù)后,最終的響應(yīng)對象將會發(fā)送給客戶端。

然后—實戰(zhàn)講解:

from flask import Flask, session

app = Flask(__name__)  # 創(chuàng)建Flask應(yīng)用程序?qū)ο?


@app.before_request
def before_request_1():
    print("Before Request 1")


@app.before_request
def before_request_2():
    print("Before Request 2")


@app.after_request
def after_request_1(response):
    print("After Request 1")
    return response


@app.after_request
def after_request_2(response):
    print("After Request 2")
    return response


@app.route('/')
def index():
    print("Index Page")
    return "Hello, World!"


if __name__ == '__main__':
    app.run()

輸出的執(zhí)行順序如下:

可以看到,首先執(zhí)行了before_request_1before_request_2兩個函數(shù),然后處理了請求并返回響應(yīng),接著按照相反的順序執(zhí)行了after_request_2after_request_1兩個函數(shù)。

最后—扒扒源碼:

為何before_request是按注冊順序執(zhí)行,而after_request是按注冊倒序執(zhí)行嘞?

扒一扒源碼就曉得啦~

直接進(jìn)入before_requestafter_request的身體:

上面就是Flask注冊before_requestafter_request函數(shù)的方法,一模一樣!

下面來扒下Flask執(zhí)行before_requestafter_request函數(shù)部分的源碼:

進(jìn)入app.__call__()后直到full_dispatch_request函數(shù):

關(guān)注點先放在上圖第二個for循環(huán),其余部分后續(xù)會慢慢探究~

before_request_funcs 就是上述包含了請求前鉤子函數(shù)的字典。這些函數(shù)會在請求分發(fā)(即dispatch_request)之前被調(diào)用。

遍歷每個注冊的請求前鉤子函數(shù),并執(zhí)行它們。如果任何一個請求前鉤子函數(shù)**返回一個非 None 的值,該值會被當(dāng)作視圖函數(shù)的返回值處理(直接返回給客戶端頁面),并且后續(xù)的請求處理流程會被停止【但是after_request正常執(zhí)行!】;**如果沒有任何請求前鉤子函數(shù)返回非 None 值,那么 preprocess_request 方法會返回 None。

來個代碼講解:

畫圖形象記憶:

綠色就是所有請求前鉤子函數(shù)(before_request)返回值都為None時的執(zhí)行流程;

相應(yīng)的,白色就是有一個返回值非None時的執(zhí)行流程。

差點忘了帶大家看after_request了!

看到?jīng)]!reversed?。?!反向遍歷哦~

第二部分:實戰(zhàn)—使用before_request進(jìn)行身份驗證

上代碼:

from flask import Flask, request, redirect, url_for, render_template, session

app = Flask(__name__)

# 模擬的用戶數(shù)據(jù)庫
users = {
    'admin': {
        'username': 'admin',
        'password': 'GuHanZhe'
    }
}


@app.before_request
def authenticate_user():
    # 獲取當(dāng)前請求的路徑
    path = request.path

    # 如果請求的路徑不是登錄頁面,進(jìn)行身份驗證
    if path != '/login':
        # 檢查 session 中是否存在已登錄的用戶
        if 'username' not in session:
            # 用戶未登錄,重定向到登錄頁面
            return redirect(url_for('login'))


@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']

        # 在實際開發(fā)中,這里需要進(jìn)行密碼驗證
        if username in users and users[username]['password'] == password:
            # 登錄成功,將用戶名保存在 session 中
            session['username'] = username
            return redirect(url_for('protected_page'))
        else:
            # 登錄失敗,顯示錯誤信息
            error_message = "Invalid username or password."
            return render_template('login.html', error_message=error_message)

    return render_template('login.html')


@app.route('/protected')
def protected_page():
    return "This is a protected page. Only logged-in users can access it."


if __name__ == '__main__':
    app.run()

在上述代碼中,before_request 鉤子函數(shù) authenticate_user 用于驗證用戶身份。它會在每個請求到達(dá)之前被調(diào)用,除了登錄頁面 /login 外的所有頁面都需要進(jìn)行身份驗證。

如果用戶未登錄,authenticate_user 函數(shù)將重定向到登錄頁面,使用 redirect 函數(shù)和 url_for 函數(shù)實現(xiàn)頁面重定向。登錄成功后,將用戶名保存在 session 中,以便在后續(xù)的請求中進(jìn)行驗證。

login 路由處理函數(shù)負(fù)責(zé)渲染登錄頁面,并接收用戶提交的表單數(shù)據(jù)。在實際應(yīng)用中,需要根據(jù)數(shù)據(jù)庫中的用戶信息進(jìn)行密碼驗證。驗證成功后,將用戶名保存在 session 中,并重定向到受保護(hù)的頁面 /protected

protected_page 路由處理函數(shù)是一個示例的受保護(hù)頁面,只有登錄用戶可見。

第三部分:補(bǔ)充常見特殊裝飾器

一、@app.errorhandler(code):

  • 這是用于注冊錯誤處理函數(shù)的裝飾器。
  • code 參數(shù)指定了需要處理的錯誤碼,例如 404、500 等。
  • 裝飾的函數(shù)將作為錯誤處理函數(shù),在出現(xiàn)指定錯誤碼時被調(diào)用,并返回自定義的錯誤頁面或響應(yīng)。

二、 @app.teardown_request:

用于注冊在每個請求結(jié)束時執(zhí)行的函數(shù)。它可以用來進(jìn)行一些清理操作或釋放資源。

實戰(zhàn):

from flask import Flask

app = Flask(__name__)


@app.route('/')
def index():
    return "Hello, World!"


@app.teardown_request
def teardown_request_func(error=None):
    print("Teardown function is called after each request.")


if __name__ == '__main__':
    app.run()

在上述代碼中,定義了一個名為 teardown_request_func 的函數(shù),并使用 @app.teardown_request 裝飾器將其注冊為每個請求結(jié)束時執(zhí)行的函數(shù)。

當(dāng)我們訪問任何路由時,F(xiàn)lask 會在請求結(jié)束后自動調(diào)用 teardown_request_func 函數(shù)。無論請求是否出現(xiàn)錯誤,該函數(shù)都會被執(zhí)行。

需要注意的是,@app.teardown_request 裝飾的函數(shù)只能接受一個參數(shù),即可選的錯誤對象。如果要訪問請求上下文中的其他對象,可以使用 flask.request 對象。

這個裝飾器通常用于進(jìn)行一些清理操作,例如關(guān)閉數(shù)據(jù)庫連接、釋放資源等。

三、@app.template_test:

用于注冊自定義模板測試函數(shù)的裝飾器。

實戰(zhàn):

from flask import Flask

app = Flask(__name__)


@app.template_test('even')
def is_even(number):
    return number % 2 == 0


if __name__ == '__main__':
    app.run()

通過 @app.template_test('even') 裝飾器將 is_even 函數(shù)注冊為一個名為 “even” 的模板測試函數(shù)。該函數(shù)用于判斷一個數(shù)字是否是偶數(shù)。

在模板中,可以使用 {% if %} 語句來調(diào)用這個模板測試函數(shù):

{% if num is even %}
    <p>The number is even</p>
{% else %}
    <p>The number is odd</p>
{% endif %}

通過注冊模板測試函數(shù),我們可以在模板中使用自定義的邏輯判斷函數(shù),以便根據(jù)特定的條件進(jìn)行動態(tài)渲染和顯示不同的內(nèi)容。

四、@app.before_first_request:

用于注冊在第一個請求到達(dá)之前執(zhí)行的函數(shù)。它只會在應(yīng)用程序啟動時執(zhí)行一次。

實戰(zhàn):

from flask import Flask

app = Flask(__name__)


@app.before_first_request
def before_first_request_func():
    print("This function is executed before the first request.")


@app.route('/')
def index():
    return "Hello, World!"


if __name__ == '__main__':
    app.run()

在上述代碼中,before_first_request_func 被裝飾為 @app.before_first_request,它會在第一個請求到達(dá)之前執(zhí)行。

當(dāng)我們運(yùn)行這個應(yīng)用程序時,before_first_request_func 函數(shù)會在第一個請求到達(dá)之前執(zhí)行一次。之后,每個請求到達(dá)時,都不會再次調(diào)用該函數(shù)。

需要注意的是,@app.before_first_request 裝飾的函數(shù)僅在主線程中執(zhí)行,并且只有在應(yīng)用程序啟動時才會被調(diào)用一次。如果使用多線程或多進(jìn)程部署應(yīng)用程序,可以考慮使用其他方法來進(jìn)行初始化操作。

【新版本Flask沒有這個裝飾器了~】

到此這篇關(guān)于Flask中特殊裝飾器的使用的文章就介紹到這了,更多相關(guān)Flask 特殊裝飾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • Python最基本的數(shù)據(jù)類型以及對元組的介紹

    Python最基本的數(shù)據(jù)類型以及對元組的介紹

    這篇文章主要介紹了Python最基本的數(shù)據(jù)類型以及對元組的介紹,來自于IBM官方網(wǎng)站技術(shù)文檔,需要的朋友可以參考下
    2015-04-04
  • Python實現(xiàn)平行坐標(biāo)圖的兩種方法小結(jié)

    Python實現(xiàn)平行坐標(biāo)圖的兩種方法小結(jié)

    今天小編就為大家分享一篇Python實現(xiàn)平行坐標(biāo)圖的兩種方法小結(jié),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • python如何讀寫json數(shù)據(jù)

    python如何讀寫json數(shù)據(jù)

    這篇文章主要為大家詳細(xì)介紹了python如何讀寫json數(shù)據(jù),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Python實現(xiàn)對特定列表進(jìn)行從小到大排序操作示例

    Python實現(xiàn)對特定列表進(jìn)行從小到大排序操作示例

    這篇文章主要介紹了Python實現(xiàn)對特定列表進(jìn)行從小到大排序操作,涉及Python文件讀取、計算、正則匹配、排序等相關(guān)操作技巧,需要的朋友可以參考下
    2019-02-02
  • Tensor 和 NumPy 相互轉(zhuǎn)換的實現(xiàn)

    Tensor 和 NumPy 相互轉(zhuǎn)換的實現(xiàn)

    本文主要介紹了Tensor 和 NumPy 相互轉(zhuǎn)換的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Python使用BeautifulSoup(bs4)解析復(fù)雜的HTML內(nèi)容

    Python使用BeautifulSoup(bs4)解析復(fù)雜的HTML內(nèi)容

    在 Web 開發(fā)和數(shù)據(jù)分析中,解析 HTML 是一個常見的任務(wù),尤其是當(dāng)你需要從網(wǎng)頁中提取數(shù)據(jù)時,Python 提供了多個庫來處理 HTML,其中最受歡迎的就是 BeautifulSoup,本文將介紹如何使用 bs4 的 BeautifulSoup 庫來解析復(fù)雜的 HTML 內(nèi)容,需要的朋友可以參考下
    2024-11-11
  • 淺談Pandas:Series和DataFrame間的算術(shù)元素

    淺談Pandas:Series和DataFrame間的算術(shù)元素

    今天小編就為大家分享一篇淺談Pandas:Series和DataFrame間的算術(shù)元素,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • python 使用元類type創(chuàng)建類

    python 使用元類type創(chuàng)建類

    這篇文章主要介紹了Python 使用元類type創(chuàng)建類,結(jié)合實例形式詳細(xì)分析了Python元類的概念、功能及元類type創(chuàng)建類對象的常見應(yīng)用技巧,需要的朋友可以參考一下文章的具體內(nèi)容。希望對你有所幫助
    2021-10-10
  • 用tensorflow構(gòu)建線性回歸模型的示例代碼

    用tensorflow構(gòu)建線性回歸模型的示例代碼

    本篇文章主要介紹了用tensorflow構(gòu)建線性回歸模型的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • python numpy格式化打印的實例

    python numpy格式化打印的實例

    今天小編就為大家分享一篇python numpy格式化打印的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05

最新評論

阆中市| 利津县| 阜康市| 仙桃市| 梅河口市| 江源县| 兴安县| 剑河县| 颍上县| 盐津县| 深水埗区| 阳信县| 天峻县| 池州市| 东山县| 蓬安县| 虞城县| 南岸区| 新源县| 博白县| 京山县| 庆元县| 余姚市| 吉安县| 奉化市| 河西区| 观塘区| 江津市| 锡林浩特市| 久治县| 古丈县| 肃宁县| 门源| 中山市| 诏安县| 噶尔县| 山阳县| 赤壁市| 张北县| 钟祥市| 陆良县|