成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

Flask中的請(qǐng)求上下文和應(yīng)用上下文

sourcenode / 2087人閱讀

摘要:并且棧頂?shù)脑囟际堑恼?qǐng)求上下文和應(yīng)用上下文之后,我們?cè)僭谶@個(gè)環(huán)境中嵌套的應(yīng)用上下文。這時(shí)查看兩個(gè)棧的內(nèi)容,發(fā)現(xiàn)兩個(gè)棧中只有的請(qǐng)求的請(qǐng)求上下文對(duì)象和應(yīng)用上下文對(duì)象。而等一直指向棧頂?shù)恼?qǐng)求上下文對(duì)象,分別引用請(qǐng)求上下文的和。

在Flask中處理請(qǐng)求時(shí),應(yīng)用會(huì)生成一個(gè)“請(qǐng)求上下文”對(duì)象。整個(gè)請(qǐng)求的處理過(guò)程,都會(huì)在這個(gè)上下文對(duì)象中進(jìn)行。這保證了請(qǐng)求的處理過(guò)程不被干擾。處理請(qǐng)求的具體代碼如下:

def wsgi_app(self, environ, start_response):
    with self.request_context(environ):
        # with語(yǔ)句中生成一個(gè)`response`對(duì)象
        ...
    return response(environ, start_response)

在Flask 0.9版本之前,應(yīng)用只有“請(qǐng)求上下文”對(duì)象,它包含了和請(qǐng)求處理相關(guān)的信息。同時(shí)Flask還根據(jù)werkzeug.local模塊中實(shí)現(xiàn)的一種數(shù)據(jù)結(jié)構(gòu)LocalStack用來(lái)存儲(chǔ)“請(qǐng)求上下文”對(duì)象。這在{% post_link 一個(gè)Flask應(yīng)用運(yùn)行過(guò)程剖析 一個(gè)Flask應(yīng)用運(yùn)行過(guò)程剖析 %}中有所介紹。在0.9版本中,F(xiàn)lask又引入了“應(yīng)用上下文”的概念。本文主要Flask中的這兩個(gè)“上下文”對(duì)象。

LocalStack

在介紹“請(qǐng)求上下文”和“應(yīng)用上下文”之前,我們對(duì)LocalStack簡(jiǎn)要做一個(gè)回顧。在Werkzeug庫(kù)——local模塊一文中,我們講解了werkzeug.local模塊中實(shí)現(xiàn)的三個(gè)類(lèi)Local、LocalStackLocalProxy。關(guān)于它們的概念和詳細(xì)介紹,可以查看上面的文章。這里,我們用一個(gè)例子來(lái)說(shuō)明Flask中使用的一種數(shù)據(jù)結(jié)構(gòu)LocalStack

>>> from werkzeug.local import LocalStack
>>> import threading

# 創(chuàng)建一個(gè)`LocalStack`對(duì)象
>>> local_stack = LocalStack()
# 查看local_stack中存儲(chǔ)的信息
>>> local_stack._local.__storage__
{}

# 定義一個(gè)函數(shù),這個(gè)函數(shù)可以向`LocalStack`中添加數(shù)據(jù)
>>> def worker(i):
        local_stack.push(i)

# 使用3個(gè)線程運(yùn)行函數(shù)`worker`
>>> for i in range(3):
        t = threading.Thread(target=worker, args=(i,))
        t.start()

# 再次查看local_stack中存儲(chǔ)的信息
>>> local_stack._local.__storage__
{: {"stack": [2]},
 : {"stack": [1]},
 : {"stack": [0]}
}

由上面的例子可以看出,存儲(chǔ)在LocalStack中的信息以字典的形式存在:鍵為線程/協(xié)程的標(biāo)識(shí)數(shù)值,值也是字典形式。每當(dāng)有一個(gè)線程/協(xié)程上要將一個(gè)對(duì)象push進(jìn)LocalStack棧中,會(huì)形成如上一個(gè)“鍵-值”對(duì)。這樣的一種結(jié)構(gòu)很好地實(shí)現(xiàn)了線程/協(xié)程的隔離,每個(gè)線程/協(xié)程都會(huì)根據(jù)自己線程/協(xié)程的標(biāo)識(shí)數(shù)值確定存儲(chǔ)在棧結(jié)構(gòu)中的值。

LocalStack還實(shí)現(xiàn)了push、pop、top等方法。其中top方法永遠(yuǎn)指向棧頂?shù)脑亍m數(shù)脑厥侵府?dāng)前線程/協(xié)程中最后被推入棧中的元素,即local_stack._local.stack[-1](注意,是stack鍵對(duì)應(yīng)的對(duì)象中最后被推入的元素)。

請(qǐng)求上下文

Flask中所有的請(qǐng)求處理都在“請(qǐng)求上下文”中進(jìn)行,在它設(shè)計(jì)之初便就有這個(gè)概念。由于0.9版本代碼比較復(fù)雜,這里還是以0.1版本的代碼為例進(jìn)行說(shuō)明。本質(zhì)上這兩個(gè)版本的“請(qǐng)求上下文”的運(yùn)行原理沒(méi)有變化,只是新版本增加了一些功能,這點(diǎn)在后面再進(jìn)行解釋。

請(qǐng)求上下文——0.1版本
# Flask v0.1
class _RequestContext(object):
    """The request context contains all request relevant information.  It is
    created at the beginning of the request and pushed to the
    `_request_ctx_stack` and removed at the end of it.  It will create the
    URL adapter and request object for the WSGI environment provided.
    """

    def __init__(self, app, environ):
        self.app = app
        self.url_adapter = app.url_map.bind_to_environ(environ)
        self.request = app.request_class(environ)
        self.session = app.open_session(self.request)
        self.g = _RequestGlobals()
        self.flashes = None

    def __enter__(self):
        _request_ctx_stack.push(self)

    def __exit__(self, exc_type, exc_value, tb):
        # do not pop the request stack if we are in debug mode and an
        # exception happened.  This will allow the debugger to still
        # access the request object in the interactive shell.
        if tb is None or not self.app.debug:
            _request_ctx_stack.pop()

由上面“請(qǐng)求上下文”的實(shí)現(xiàn)可知:

“請(qǐng)求上下文”是一個(gè)上下文對(duì)象,實(shí)現(xiàn)了__enter____exit__方法??梢允褂?b>with語(yǔ)句構(gòu)造一個(gè)上下文環(huán)境。

進(jìn)入上下文環(huán)境時(shí),_request_ctx_stack這個(gè)棧中會(huì)推入一個(gè)_RequestContext對(duì)象。這個(gè)棧結(jié)構(gòu)就是上面講的LocalStack棧。

推入棧中的_RequestContext對(duì)象有一些屬性,包含了請(qǐng)求的的所有相關(guān)信息。例如app、request、sessiong、flashes。還有一個(gè)url_adapter,這個(gè)對(duì)象可以進(jìn)行URL匹配。

with語(yǔ)句構(gòu)造的上下文環(huán)境中可以進(jìn)行請(qǐng)求處理。當(dāng)退出上下文環(huán)境時(shí),_request_ctx_stack這個(gè)棧會(huì)銷(xiāo)毀剛才存儲(chǔ)的上下文對(duì)象。

以上的運(yùn)行邏輯使得請(qǐng)求的處理始終在一個(gè)上下文環(huán)境中,這保證了請(qǐng)求處理過(guò)程不被干擾,而且請(qǐng)求上下文對(duì)象保存在LocalStack棧中,也很好地實(shí)現(xiàn)了線程/協(xié)程的隔離。

以下是一個(gè)簡(jiǎn)單的例子:

# example - Flask v0.1
>>> from flask import Flask, _request_ctx_stack
>>> import threading
>>> app = Flask(__name__)
# 先觀察_request_ctx_stack中包含的信息
>>> _request_ctx_stack._local.__storage__
{}

# 創(chuàng)建一個(gè)函數(shù),用于向棧中推入請(qǐng)求上下文
# 本例中不使用`with`語(yǔ)句
>>> def worker():
        # 使用應(yīng)用的test_request_context()方法創(chuàng)建請(qǐng)求上下文
        request_context = app.test_request_context()
        _request_ctx_stack.push(request_context)

# 創(chuàng)建3個(gè)進(jìn)程分別執(zhí)行worker方法
>>> for i in range(3):
        t = threading.Thread(target=worker)
        t.start()

# 再觀察_request_ctx_stack中包含的信息
>>> _request_ctx_stack._local.__storage__
{: {"stack": []},
 : {"stack": []},
 : {"stack": []}
}

上面的結(jié)果顯示:_request_ctx_stack中為每一個(gè)線程創(chuàng)建了一個(gè)“鍵-值”對(duì),每一“鍵-值”對(duì)中包含一個(gè)請(qǐng)求上下文對(duì)象。如果使用with語(yǔ)句,在離開(kāi)上下文環(huán)境時(shí)棧中銷(xiāo)毀存儲(chǔ)的上下文對(duì)象信息。

請(qǐng)求上下文——0.9版本

在0.9版本中,F(xiàn)lask引入了“應(yīng)用上下文”的概念,這對(duì)“請(qǐng)求上下文”的實(shí)現(xiàn)有一定的改變。這個(gè)版本的“請(qǐng)求上下文”也是一個(gè)上下文對(duì)象。在使用with語(yǔ)句進(jìn)入上下文環(huán)境后,_request_ctx_stack會(huì)存儲(chǔ)這個(gè)上下文對(duì)象。不過(guò)與0.1版本相比,有以下幾點(diǎn)改變:

請(qǐng)求上下文實(shí)現(xiàn)了pushpop方法,這使得對(duì)于請(qǐng)求上下文的操作更加的靈活;

伴隨著請(qǐng)求上下文對(duì)象的生成并存儲(chǔ)在棧結(jié)構(gòu)中,F(xiàn)lask還會(huì)生成一個(gè)“應(yīng)用上下文”對(duì)象,而且“應(yīng)用上下文”對(duì)象也會(huì)存儲(chǔ)在另一個(gè)棧結(jié)構(gòu)中去。這是兩個(gè)版本最大的不同。

我們先看一下0.9版本相關(guān)的代碼:

# Flask v0.9
def push(self):
    """Binds the request context to the current context."""
    top = _request_ctx_stack.top
    if top is not None and top.preserved:
        top.pop()

    # Before we push the request context we have to ensure that there
    # is an application context.
    app_ctx = _app_ctx_stack.top
    if app_ctx is None or app_ctx.app != self.app:
        app_ctx = self.app.app_context()
        app_ctx.push()
        self._implicit_app_ctx_stack.append(app_ctx)
    else:
        self._implicit_app_ctx_stack.append(None)

    _request_ctx_stack.push(self)

    self.session = self.app.open_session(self.request)
    if self.session is None:
        self.session = self.app.make_null_session()

我們注意到,0.9版本的“請(qǐng)求上下文”的pop方法中,當(dāng)要將一個(gè)“請(qǐng)求上下文”推入_request_ctx_stack棧中的時(shí)候,會(huì)先檢查另一個(gè)棧_app_ctx_stack的棧頂是否存在“應(yīng)用上下文”對(duì)象或者棧頂?shù)摹皯?yīng)用上下文”對(duì)象的應(yīng)用是否是當(dāng)前應(yīng)用。如果不存在或者不是當(dāng)前對(duì)象,F(xiàn)lask會(huì)自動(dòng)先生成一個(gè)“應(yīng)用上下文”對(duì)象,并將其推入_app_ctx_stack中。

我們?cè)倏措x開(kāi)上下文時(shí)的相關(guān)代碼:

# Flask v0.9
def pop(self, exc=None):
    """Pops the request context and unbinds it by doing that.  This will
    also trigger the execution of functions registered by the
    :meth:`~flask.Flask.teardown_request` decorator.

    .. versionchanged:: 0.9
       Added the `exc` argument.
    """
    app_ctx = self._implicit_app_ctx_stack.pop()

    clear_request = False
    if not self._implicit_app_ctx_stack:
        self.preserved = False
        if exc is None:
            exc = sys.exc_info()[1]
        self.app.do_teardown_request(exc)
        clear_request = True

    rv = _request_ctx_stack.pop()
    assert rv is self, "Popped wrong request context.  (%r instead of %r)" 
        % (rv, self)

    # get rid of circular dependencies at the end of the request
    # so that we don"t require the GC to be active.
    if clear_request:
        rv.request.environ["werkzeug.request"] = None

    # Get rid of the app as well if necessary.
    if app_ctx is not None:
        app_ctx.pop(exc)

上面代碼中的細(xì)節(jié)先不討論。注意到當(dāng)要離開(kāi)以上“請(qǐng)求上下文”環(huán)境的時(shí)候,F(xiàn)lask會(huì)先將“請(qǐng)求上下文”對(duì)象從_request_ctx_stack棧中銷(xiāo)毀,之后會(huì)根據(jù)實(shí)際的情況確定銷(xiāo)毀“應(yīng)用上下文”對(duì)象。

以下還是以一個(gè)簡(jiǎn)單的例子進(jìn)行說(shuō)明:

# example - Flask v0.9
>>> from flask import Flask, _request_ctx_stack, _app_ctx_stack
>>> app = Flask(__name__)

# 先檢查兩個(gè)棧的內(nèi)容
>>> _request_ctx_stack._local.__storage__
{}
>>> _app_ctx_stack._local.__storage__
{}

# 生成一個(gè)請(qǐng)求上下文對(duì)象
>>> request_context = app.test_request_context()
>>> request_context.push()

# 請(qǐng)求上下文推入棧后,再次查看兩個(gè)棧的內(nèi)容
>>> _request_ctx_stack._local.__storage__
{: {"stack": []}}
>>> _app_ctx_stack._local.__storage__
{: {"stack": []}}

>>> request_context.pop()

# 銷(xiāo)毀請(qǐng)求上下文時(shí),再次查看兩個(gè)棧的內(nèi)容
>>> _request_ctx_stack._local.__storage__
{}
>>> _app_ctx_stack._local.__storage__
{}
應(yīng)用上下文

上部分中簡(jiǎn)單介紹了“應(yīng)用上下文”和“請(qǐng)求上下文”的關(guān)系。那什么是“應(yīng)用上下文”呢?我們先看一下它的類(lèi):

class AppContext(object):
    """The application context binds an application object implicitly
    to the current thread or greenlet, similar to how the
    :class:`RequestContext` binds request information.  The application
    context is also implicitly created if a request context is created
    but the application is not on top of the individual application
    context.
    """

    def __init__(self, app):
        self.app = app
        self.url_adapter = app.create_url_adapter(None)

        # Like request context, app contexts can be pushed multiple times
        # but there a basic "refcount" is enough to track them.
        self._refcnt = 0

    def push(self):
        """Binds the app context to the current context."""
        self._refcnt += 1
        _app_ctx_stack.push(self)

    def pop(self, exc=None):
        """Pops the app context."""
        self._refcnt -= 1
        if self._refcnt <= 0:
            if exc is None:
                exc = sys.exc_info()[1]
            self.app.do_teardown_appcontext(exc)
        rv = _app_ctx_stack.pop()
        assert rv is self, "Popped wrong app context.  (%r instead of %r)" 
            % (rv, self)

    def __enter__(self):
        self.push()
        return self

    def __exit__(self, exc_type, exc_value, tb):
        self.pop(exc_value)

由以上代碼可以看出:“應(yīng)用上下文”也是一個(gè)上下文對(duì)象,可以使用with語(yǔ)句構(gòu)造一個(gè)上下文環(huán)境,它也實(shí)現(xiàn)了push、pop等方法?!皯?yīng)用上下文”的構(gòu)造函數(shù)也和“請(qǐng)求上下文”類(lèi)似,都有app、url_adapter等屬性?!皯?yīng)用上下文”存在的一個(gè)主要功能就是確定請(qǐng)求所在的應(yīng)用。

然而,以上的論述卻又讓人產(chǎn)生這樣的疑問(wèn):既然“請(qǐng)求上下文”中也包含app等和當(dāng)前應(yīng)用相關(guān)的信息,那么只要調(diào)用_request_ctx_stack.top.app或者魔法current_app就可以確定請(qǐng)求所在的應(yīng)用了,那為什么還需要“應(yīng)用上下文”對(duì)象呢?對(duì)于單應(yīng)用單請(qǐng)求來(lái)說(shuō),使用“請(qǐng)求上下文”確實(shí)就可以了。然而,F(xiàn)lask的設(shè)計(jì)理念之一就是多應(yīng)用的支持。當(dāng)在一個(gè)應(yīng)用的請(qǐng)求上下文環(huán)境中,需要嵌套處理另一個(gè)應(yīng)用的相關(guān)操作時(shí),“請(qǐng)求上下文”顯然就不能很好地解決問(wèn)題了。如何讓請(qǐng)求找到“正確”的應(yīng)用呢?我們可能會(huì)想到,可以再增加一個(gè)請(qǐng)求上下文環(huán)境,并將其推入_request_ctx_stack棧中。由于兩個(gè)上下文環(huán)境的運(yùn)行是獨(dú)立的,不會(huì)相互干擾,所以通過(guò)調(diào)用_request_ctx_stack.top.app或者魔法current_app也可以獲得當(dāng)前上下文環(huán)境正在處理哪個(gè)應(yīng)用。這種辦法在一定程度上可行,但是如果對(duì)于第二個(gè)應(yīng)用的處理不涉及到相關(guān)請(qǐng)求,那也就無(wú)從談起“請(qǐng)求上下文”。

為了應(yīng)對(duì)這個(gè)問(wèn)題,F(xiàn)lask中將應(yīng)用相關(guān)的信息多帶帶拿出來(lái),形成一個(gè)“應(yīng)用上下文”對(duì)象。這個(gè)對(duì)象可以和“請(qǐng)求上下文”一起使用,也可以多帶帶拿出來(lái)使用。不過(guò)有一點(diǎn)需要注意的是:在創(chuàng)建“請(qǐng)求上下文”時(shí)一定要?jiǎng)?chuàng)建一個(gè)“應(yīng)用上下文”對(duì)象。有了“應(yīng)用上下文”對(duì)象,便可以很容易地確定當(dāng)前處理哪個(gè)應(yīng)用,這就是魔法current_app。在0.1版本中,current_app是對(duì)_request_ctx_stack.top.app的引用,而在0.9版本中current_app是對(duì)_app_ctx_stack.top.app的引用。

下面以一個(gè)多應(yīng)用的例子進(jìn)行說(shuō)明:

# example - Flask v0.9
>>> from flask import Flask, _request_ctx_stack, _app_ctx_stack
# 創(chuàng)建兩個(gè)Flask應(yīng)用
>>> app = Flask(__name__)
>>> app2 = Flask(__name__)
# 先查看兩個(gè)棧中的內(nèi)容
>>> _request_ctx_stack._local.__storage__
{}
>>> _app_ctx_stack._local.__storage__
{}
# 構(gòu)建一個(gè)app的請(qǐng)求上下文環(huán)境,在這個(gè)環(huán)境中運(yùn)行app2的相關(guān)操作
>>> with app.test_request_context():
        print "Enter app"s Request Context:"
        print _request_ctx_stack._local.__storage__
        print _app_ctx_stack._local.__storage__
        print
        with app2.app_context():
            print "Enter app2"s App Context:"
            print _request_ctx_stack._local.__storage__
            print _app_ctx_stack._local.__storage__
            print
            # do something
        print "Exit app2"s App Context:"
        print _request_ctx_stack._local.__storage__
        print _app_ctx_stack._local.__storage__
        print
# Result
Enter app"s Request Context:
{: {"stack": []}}
{: {"stack": []}}

Enter app2"s App Context:
{: {"stack": []}}
{: {"stack": [, ]}}

Exit app2"s App Context
{: {"stack": []}}
{: {"stack": []}}

在以上的例子中:

我們首先創(chuàng)建了兩個(gè)Flask應(yīng)用appapp2

接著我們構(gòu)建了一個(gè)app的請(qǐng)求上下文環(huán)境。當(dāng)進(jìn)入這個(gè)環(huán)境中時(shí),這時(shí)查看兩個(gè)棧的內(nèi)容,發(fā)現(xiàn)兩個(gè)棧中已經(jīng)有了當(dāng)前請(qǐng)求的請(qǐng)求上下文對(duì)象和應(yīng)用上下文對(duì)象。并且棧頂?shù)脑囟际?b>app的請(qǐng)求上下文和應(yīng)用上下文;

之后,我們?cè)僭谶@個(gè)環(huán)境中嵌套app2的應(yīng)用上下文。當(dāng)進(jìn)入app2的應(yīng)用上下文環(huán)境時(shí),兩個(gè)上下文環(huán)境便隔離開(kāi)來(lái),此時(shí)再查看兩個(gè)棧的內(nèi)容,發(fā)現(xiàn)_app_ctx_stack中推入了app2的應(yīng)用上下文對(duì)象,并且棧頂指向它。這時(shí)在app2的應(yīng)用上下文環(huán)境中,current_app便會(huì)一直指向app2;

當(dāng)離開(kāi)app2的應(yīng)用上下文環(huán)境,_app_ctx_stack棧便會(huì)銷(xiāo)毀app2的應(yīng)用上下文對(duì)象。這時(shí)查看兩個(gè)棧的內(nèi)容,發(fā)現(xiàn)兩個(gè)棧中只有app的請(qǐng)求的請(qǐng)求上下文對(duì)象和應(yīng)用上下文對(duì)象。

最后,離開(kāi)app的請(qǐng)求上下文環(huán)境后,兩個(gè)棧便會(huì)銷(xiāo)毀app的請(qǐng)求的請(qǐng)求上下文對(duì)象和應(yīng)用上下文對(duì)象,棧為空。

與上下文對(duì)象有關(guān)的“全局變量”

在Flask中,為了更加方便地處理一些變量,特地提出了“全局變量”的概念。這些全局變量有:

# Flask v0.9
_request_ctx_stack = LocalStack()
_app_ctx_stack = LocalStack()
current_app = LocalProxy(_find_app)
request = LocalProxy(partial(_lookup_object, "request"))
session = LocalProxy(partial(_lookup_object, "session"))
g = LocalProxy(partial(_lookup_object, "g"))

# 輔助函數(shù)
def _lookup_object(name):
    top = _request_ctx_stack.top
    if top is None:
        raise RuntimeError("working outside of request context")
    return getattr(top, name)


def _find_app():
    top = _app_ctx_stack.top
    if top is None:
        raise RuntimeError("working outside of application context")
    return top.app

可以看出,F(xiàn)lask中使用的一些“全局變量”,包括current_app、requestsession、g等都來(lái)自于上下文對(duì)象。其中current_app一直指向_app_ctx_stack棧頂?shù)摹皯?yīng)用上下文”對(duì)象,是對(duì)當(dāng)前應(yīng)用的引用。而request、sessiong等一直指向_request_ctx_stack棧頂?shù)摹罢?qǐng)求上下文”對(duì)象,分別引用請(qǐng)求上下文的requestsessiong。不過(guò),從 Flask 0.10 起,對(duì)象 g 存儲(chǔ)在應(yīng)用上下文中而不再是請(qǐng)求上下文中。

另外一個(gè)問(wèn)題,在形成這些“全局變量”的時(shí)候,使用了werkzeug.local模塊的LocalProxy類(lèi)。之所以要用該類(lèi),主要是為了動(dòng)態(tài)地實(shí)現(xiàn)對(duì)棧頂元素的引用。如果不使用這個(gè)類(lèi),在生成上述“全局變量”的時(shí)候,它們因?yàn)橹赶驐m斣兀鴹m斣卮藭r(shí)為None,所以這些變量也會(huì)被設(shè)置為None常量。后續(xù)即使有上下文對(duì)象被推入棧中,相應(yīng)的“全局變量”也不會(huì)發(fā)生改變。為了動(dòng)態(tài)地實(shí)現(xiàn)對(duì)棧頂元素的引用,這里必須使用werkzeug.local模塊的LocalProxy類(lèi)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/38604.html

相關(guān)文章

  • 一個(gè)Flask應(yīng)用運(yùn)行過(guò)程剖析

    摘要:本文就主要針對(duì)一個(gè)應(yīng)用的運(yùn)行過(guò)程進(jìn)行簡(jiǎn)要分析,后續(xù)文章還會(huì)對(duì)框架的一些具體問(wèn)題進(jìn)行分析。所有的請(qǐng)求處理過(guò)程,都會(huì)在這個(gè)上下文對(duì)象中進(jìn)行。和一些全局變量注意當(dāng)進(jìn)入這個(gè)上下文對(duì)象時(shí),會(huì)觸發(fā)。 相信很多初學(xué)Flask的同學(xué)(包括我自己),在閱讀官方文檔或者Flask的學(xué)習(xí)資料時(shí),對(duì)于它的認(rèn)識(shí)是從以下的一段代碼開(kāi)始的: from flask import Flask app = Flask(...

    shmily 評(píng)論0 收藏0
  • [貳]Flask web開(kāi)發(fā):程序的基本結(jié)構(gòu)

    摘要:本篇對(duì)應(yīng)書(shū)本第二章程序的基本結(jié)構(gòu)。初始化導(dǎo)入模塊創(chuàng)建類(lèi)的實(shí)例注對(duì)于開(kāi)發(fā)者來(lái)說(shuō),傳給應(yīng)用程序構(gòu)造函數(shù)的參數(shù)是比較容易弄混淆的。不同的請(qǐng)求方法發(fā)送到相同的上時(shí),會(huì)使用不同的視圖函數(shù)進(jìn)行處理。 本系列筆記是我閱讀Miguel Grinberg的《Flask Web Development》的筆記,標(biāo)題與書(shū)本同步。希望通過(guò)記錄技術(shù)筆記的方式促進(jìn)自己對(duì)知識(shí)的理解。 本篇對(duì)應(yīng)書(shū)本第二章:程序的基本...

    maxmin 評(píng)論0 收藏0
  • flask 核心 之 應(yīng)用下文請(qǐng)求下文

    摘要:的上下文對(duì)象有兩種上下文,分別是請(qǐng)求上下文請(qǐng)求的對(duì)象,封裝了請(qǐng)求的內(nèi)容,生命周期請(qǐng)求處理完就結(jié)束了根據(jù)請(qǐng)求中的,重新載入該訪問(wèn)者相關(guān)的會(huì)話信息應(yīng)用上下文處理請(qǐng)求時(shí)用作臨時(shí)存儲(chǔ)的對(duì)象。 Werkzeugs 是 Flask 的底層WSGI庫(kù)。 什么是WSGI? showImg(https://s1.ax1x.com/2018/11/13/iOqdKS.jpg); 一段簡(jiǎn)單的app: def...

    tinna 評(píng)論0 收藏0
  • flask接收請(qǐng)求并推入棧

    摘要:前面兩篇講明了怎么支持多線程以及怎么開(kāi)啟多線程的這篇來(lái)講講當(dāng)后端接收到請(qǐng)求后是怎么一步步封裝的類(lèi)中的當(dāng)應(yīng)用啟動(dòng)后會(huì)通過(guò)接收請(qǐng)求中返回的是方法主要做了兩件事情第一件事是通過(guò)的另一個(gè)方法返回得到了一個(gè)封裝好的對(duì)象然后調(diào)用中的在最后調(diào)用了將請(qǐng)求對(duì) 前面兩篇講明了flask怎么支持多線程以及怎么開(kāi)啟多線程的,這篇來(lái)講講當(dāng)后端接收到請(qǐng)求后是怎么一步步封裝的 Flask類(lèi)中的wsgi_app()當(dāng)...

    崔曉明 評(píng)論0 收藏0
  • 深入理解flask框架(2):應(yīng)用下文請(qǐng)求下文

    摘要:實(shí)現(xiàn)一個(gè)進(jìn)程中擁有多個(gè)應(yīng)用上下文機(jī)制依賴的數(shù)據(jù)結(jié)構(gòu)上下文機(jī)制的實(shí)現(xiàn)基于的。 什么是上下文? flask框架中的上下文本質(zhì)上就是兩個(gè)類(lèi),我們可以先看一下他的初始化函數(shù):應(yīng)用上下文 class AppContext(object): The application context binds an application object implicitly to the c...

    wushuiyong 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<