日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Flask中的請求上下文和應(yīng)用上下文

在Flask中處理請求時,應(yīng)用會生成一個“請求上下文”對象。整個請求的處理過程,都會在這個上下文對象中進行。這保證了請求的處理過程不被干擾。處理請求的具體代碼如下:

創(chuàng)新互聯(lián)建站專業(yè)提供成都移動機房服務(wù),為用戶提供五星數(shù)據(jù)中心、電信、雙線接入解決方案,用戶可自行在線購買成都移動機房服務(wù),并享受7*24小時金牌售后服務(wù)。

 
 
 
  1. def wsgi_app(self, environ, start_response): 
  2.  
  3.     with self.request_context(environ): 
  4.  
  5.         # with語句中生成一個`response`對象 
  6.  
  7.         ... 
  8.  
  9.     return response(environ, start_response)  

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

LocalStack

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

 
 
 
  1. >>> from werkzeug.local import LocalStack 
  2.  
  3. >>> import threading 
  4.  
  5.   
  6.  
  7. # 創(chuàng)建一個`LocalStack`對象 
  8.  
  9. >>> local_stack = LocalStack() 
  10.  
  11. # 查看local_stack中存儲的信息 
  12.  
  13. >>> local_stack._local.__storage__ 
  14.  
  15. {} 
  16.  
  17.   
  18.  
  19. # 定義一個函數(shù),這個函數(shù)可以向`LocalStack`中添加數(shù)據(jù) 
  20.  
  21. >>> def worker(i): 
  22.  
  23.         local_stack.push(i) 
  24.  
  25.   
  26.  
  27. # 使用3個線程運行函數(shù)`worker` 
  28.  
  29. >>> for i in range(3): 
  30.  
  31.         t = threading.Thread(target=worker, args=(i,)) 
  32.  
  33.         t.start() 
  34.  
  35.   
  36.  
  37. # 再次查看local_stack中存儲的信息 
  38.  
  39. >>> local_stack._local.__storage__ 
  40.  
  41. {: {'stack': [2]}, 
  42.  
  43. : {'stack': [1]}, 
  44.  
  45. : {'stack': [0]} 
  46.  
  47. }  

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

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

請求上下文

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

請求上下文——0.1版本

 
 
 
  1. # Flask v0.1 
  2.  
  3. class _RequestContext(object): 
  4.  
  5.     """The request context contains all request relevant information.  It is 
  6.  
  7.     created at the beginning of the request and pushed to the 
  8.  
  9.     `_request_ctx_stack` and removed at the end of it.  It will create the 
  10.  
  11.     URL adapter and request object for the WSGI environment provided. 
  12.  
  13.     """ 
  14.  
  15.   
  16.  
  17.     def __init__(self, app, environ): 
  18.  
  19.         self.app = app 
  20.  
  21.         self.url_adapter = app.url_map.bind_to_environ(environ) 
  22.  
  23.         self.request = app.request_class(environ) 
  24.  
  25.         self.session = app.open_session(self.request) 
  26.  
  27.         self.g = _RequestGlobals() 
  28.  
  29.         self.flashes = None 
  30.  
  31.   
  32.  
  33.     def __enter__(self): 
  34.  
  35.         _request_ctx_stack.push(self) 
  36.  
  37.   
  38.  
  39.     def __exit__(self, exc_type, exc_value, tb): 
  40.  
  41.         # do not pop the request stack if we are in debug mode and an 
  42.  
  43.         # exception happened.  This will allow the debugger to still 
  44.  
  45.         # access the request object in the interactive shell. 
  46.  
  47.         if tb is None or not self.app.debug: 
  48.  
  49.             _request_ctx_stack.pop()  

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

  • “請求上下文”是一個上下文對象,實現(xiàn)了__enter__和__exit__方法??梢允褂脀ith語句構(gòu)造一個上下文環(huán)境。
  • 進入上下文環(huán)境時,_request_ctx_stack這個棧中會推入一個_RequestContext對象。這個棧結(jié)構(gòu)就是上面講的LocalStack棧。
  • 推入棧中的_RequestContext對象有一些屬性,包含了請求的的所有相關(guān)信息。例如app、request、session、g、flashes。還有一個url_adapter,這個對象可以進行URL匹配。
  • 在with語句構(gòu)造的上下文環(huán)境中可以進行請求處理。當(dāng)退出上下文環(huán)境時,_request_ctx_stack這個棧會銷毀剛才存儲的上下文對象。
  • 以上的運行邏輯使得請求的處理始終在一個上下文環(huán)境中,這保證了請求處理過程不被干擾,而且請求上下文對象保存在LocalStack棧中,也很好地實現(xiàn)了線程/協(xié)程的隔離。

以下是一個簡單的例子:

 
 
 
  1. # example - Flask v0.1 
  2.  
  3. >>> from flask import Flask, _request_ctx_stack 
  4.  
  5. >>> import threading 
  6.  
  7. >>> app = Flask(__name__) 
  8.  
  9. # 先觀察_request_ctx_stack中包含的信息 
  10.  
  11. >>> _request_ctx_stack._local.__storage__ 
  12.  
  13. {} 
  14.  
  15.   
  16.  
  17. # 創(chuàng)建一個函數(shù),用于向棧中推入請求上下文 
  18.  
  19. # 本例中不使用`with`語句 
  20.  
  21. >>> def worker(): 
  22.  
  23.         # 使用應(yīng)用的test_request_context()方法創(chuàng)建請求上下文 
  24.  
  25.         request_context = app.test_request_context() 
  26.  
  27.         _request_ctx_stack.push(request_context) 
  28.  
  29.   
  30.  
  31. # 創(chuàng)建3個進程分別執(zhí)行worker方法 
  32.  
  33. >>> for i in range(3): 
  34.  
  35.         t = threading.Thread(target=worker) 
  36.  
  37.         t.start() 
  38.  
  39.   
  40.  
  41. # 再觀察_request_ctx_stack中包含的信息 
  42.  
  43. >>> _request_ctx_stack._local.__storage__ 
  44.  
  45. {: {'stack': []}, 
  46.  
  47. : {'stack': []}, 
  48.  
  49. : {'stack': []} 
  50.  
  51. }  

上面的結(jié)果顯示:_request_ctx_stack中為每一個線程創(chuàng)建了一個“鍵-值”對,每一“鍵-值”對中包含一個請求上下文對象。如果使用with語句,在離開上下文環(huán)境時棧中銷毀存儲的上下文對象信息。

請求上下文——0.9版本

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

  • 請求上下文實現(xiàn)了push、pop方法,這使得對于請求上下文的操作更加的靈活;
  • 伴隨著請求上下文對象的生成并存儲在棧結(jié)構(gòu)中,F(xiàn)lask還會生成一個“應(yīng)用上下文”對象,而且“應(yīng)用上下文”對象也會存儲在另一個棧結(jié)構(gòu)中去。這是兩個版本***的不同。

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

 
 
 
  1. # Flask v0.9 
  2.  
  3. def push(self): 
  4.  
  5.     """Binds the request context to the current context.""" 
  6.  
  7.     top = _request_ctx_stack.top 
  8.  
  9.     if top is not None and top.preserved: 
  10.  
  11.         top.pop() 
  12.  
  13.   
  14.  
  15.     # Before we push the request context we have to ensure that there 
  16.  
  17.     # is an application context. 
  18.  
  19.     app_ctx = _app_ctx_stack.top 
  20.  
  21.     if app_ctx is None or app_ctx.app != self.app: 
  22.  
  23.         app_ctx = self.app.app_context() 
  24.  
  25.         app_ctx.push() 
  26.  
  27.         self._implicit_app_ctx_stack.append(app_ctx) 
  28.  
  29.     else: 
  30.  
  31.         self._implicit_app_ctx_stack.append(None) 
  32.  
  33.   
  34.  
  35.     _request_ctx_stack.push(self) 
  36.  
  37.   
  38.  
  39.     self.session = self.app.open_session(self.request) 
  40.  
  41.     if self.session is None: 
  42.  
  43.         self.session = self.app.make_null_session()  

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

我們再看離開上下文時的相關(guān)代碼:

 
 
 
  1. # Flask v0.9 
  2.  
  3. def pop(self, exc=None): 
  4.  
  5.     """Pops the request context and unbinds it by doing that.  This will 
  6.  
  7.     also trigger the execution of functions registered by the 
  8.  
  9.     :meth:`~flask.Flask.teardown_request` decorator. 
  10.  
  11.   
  12.  
  13.     .. versionchanged:: 0.9 
  14.  
  15.        Added the `exc` argument. 
  16.  
  17.     """ 
  18.  
  19.     app_ctx = self._implicit_app_ctx_stack.pop() 
  20.  
  21.   
  22.  
  23.     clear_request = False 
  24.  
  25.     if not self._implicit_app_ctx_stack: 
  26.  
  27.         self.preserved = False 
  28.  
  29.         if exc is None: 
  30.  
  31.             exc = sys.exc_info()[1] 
  32.  
  33.         self.app.do_teardown_request(exc) 
  34.  
  35.         clear_request = True 
  36.  
  37.   
  38.  
  39.     rv = _request_ctx_stack.pop() 
  40.  
  41.     assert rv is self, 'Popped wrong request context.  (%r instead of %r)' 
  42.  
  43.         % (rv, self) 
  44.  
  45.   
  46.  
  47.     # get rid of circular dependencies at the end of the request 
  48.  
  49.     # so that we don't require the GC to be active. 
  50.  
  51.     if clear_request: 
  52.  
  53.         rv.request.environ['werkzeug.request'] = None 
  54.  
  55.   
  56.  
  57.     # Get rid of the app as well if necessary. 
  58.  
  59.     if app_ctx is not None: 
  60.  
  61.         app_ctx.pop(exc)  

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

以下還是以一個簡單的例子進行說明:

 
 
 
  1. # example - Flask v0.9 
  2.  
  3. >>> from flask import Flask, _request_ctx_stack, _app_ctx_stack 
  4.  
  5. >>> app = Flask(__name__) 
  6.  
  7.   
  8.  
  9. # 先檢查兩個棧的內(nèi)容 
  10.  
  11. >>> _request_ctx_stack._local.__storage__ 
  12.  
  13. {} 
  14.  
  15. >>> _app_ctx_stack._local.__storage__ 
  16.  
  17. {} 
  18.  
  19.   
  20.  
  21. # 生成一個請求上下文對象 
  22.  
  23. >>> request_context = app.test_request_context() 
  24.  
  25. >>> request_context.push() 
  26.  
  27.   
  28.  
  29. # 請求上下文推入棧后,再次查看兩個棧的內(nèi)容 
  30.  
  31. >>> _request_ctx_stack._local.__storage__ 
  32.  
  33. {: {'stack': []}} 
  34.  
  35. >>> _app_ctx_stack._local.__storage__ 
  36.  
  37. {: {'stack': []}} 
  38.  
  39.   
  40.  
  41. >>> request_context.pop() 
  42.  
  43.   
  44.  
  45. # 銷毀請求上下文時,再次查看兩個棧的內(nèi)容 
  46.  
  47. >>> _request_ctx_stack._local.__storage__ 
  48.  
  49. {} 
  50.  
  51. >>> _app_ctx_stack._local.__storage__ 
  52.  
  53. {}  

應(yīng)用上下文

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

 
 
 
  1. class AppContext(object): 
  2.  
  3.     """The application context binds an application object implicitly 
  4.  
  5.     to the current thread or greenlet, similar to how the 
  6.  
  7.     :class:`RequestContext` binds request information.  The application 
  8.  
  9.     context is also implicitly created if a request context is created 
  10.  
  11.     but the application is not on top of the individual application 
  12.  
  13.     context. 
  14.  
  15.     """ 
  16.  
  17.   
  18.  
  19.     def __init__(self, app): 
  20.  
  21.         self.app = app 
  22.  
  23.         self.url_adapter = app.create_url_adapter(None) 
  24.  
  25.   
  26.  
  27.         # Like request context, app contexts can be pushed multiple times 
  28.  
  29.         # but there a basic "refcount" is enough to track them. 
  30.  
  31.         self._refcnt = 0 
  32.  
  33.   
  34.  
  35.     def push(self): 
  36.  
  37.         """Binds the app context to the current context.""" 
  38.  
  39.         self._refcnt += 1 
  40.  
  41.         _app_ctx_stack.push(self) 
  42.  
  43.   
  44.  
  45.     def pop(self, exc=None): 
  46.  
  47.         """Pops the app context.""" 
  48.  
  49.         self._refcnt -= 1 
  50.  
  51.         if self._refcnt <= 0: 
  52.  
  53.             if exc is None: 
  54.  
  55.                 exc = sys.exc_info()[1] 
  56.  
  57.             self.app.do_teardown_appcontext(exc) 
  58.  
  59.         rv = _app_ctx_stack.pop() 
  60.  
  61.         assert rv is self, 'Popped wrong app context.  (%r instead of %r)' \ 
  62.  
  63.             % (rv, self) 
  64.  
  65.   
  66.  
  67.     def __enter__(self):  

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

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

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

下面以一個多應(yīng)用的例子進行說明:

 
 
 
  1. # example - Flask v0.9 
  2.  
  3. >>> from flask import Flask, _request_ctx_stack, _app_ctx_stack 
  4.  
  5. # 創(chuàng)建兩個Flask應(yīng)用 
  6.  
  7. >>> app = Flask(__name__) 
  8.  
  9. >>> app2 = Flask(__name__) 
  10.  
  11. # 先查看兩個棧中的內(nèi)容 
  12.  
  13. >>> _request_ctx_stack._local.__storage__ 
  14.  
  15. {} 
  16.  
  17. >>> _app_ctx_stack._local.__storage__ 
  18.  
  19. {} 
  20.  
  21. # 構(gòu)建一個app的請求上下文環(huán)境,在這個環(huán)境中運行app2的相關(guān)操作 
  22.  
  23. >>> with app.test_request_context(): 
  24.  
  25.         print "Enter app's Request Context:" 
  26.  
  27.         print _request_ctx_stack._local.__storage__ 
  28.  
  29.         print _app_ctx_stack._local.__storage__ 
  30.  
  31.         print 
  32.  
  33.         with app2.app_context(): 
  34.  
  35.             print "Enter app2's App Context:" 
  36.  
  37.             print _request_ctx_stack._local.__storage__ 
  38.  
  39.             print _app_ctx_stack._local.__storage__ 
  40.  
  41.             print 
  42.  
  43.             # do something 
  44.  
  45.         print "Exit app2's App Context:" 
  46.  
  47.         print _request_ctx_stack._local.__storage__ 
  48.  
  49.         print _app_ctx_stack._local.__storage__ 
  50.  
  51.         print 
  52.  
  53. # Result 
  54.  
  55. Enter app's Request Context: 
  56.  
  57. {: {'stack': []}} 
  58.  
  59. {: {'stack': []}} 
  60.  
  61.   
  62.  
  63. Enter app2's App Context: 
  64.  
  65. {: {'stack': []}} 
  66.  
  67. {: {'stack': []}} 
  68.  
  69.   
  70.  
  71. Exit app2's App Context 
  72.  
  73. {: {'stack': []}} 
  74.  
  75. {: {'stack': []}}  

在以上的例子中:

  • 我們首先創(chuàng)建了兩個Flask應(yīng)用app和app2;
  • 接著我們構(gòu)建了一個app的請求上下文環(huán)境。當(dāng)進入這個環(huán)境中時,這時查看兩個棧的內(nèi)容,發(fā)現(xiàn)兩個棧中已經(jīng)有了當(dāng)前請求的請求上下文對象和應(yīng)用上下文對象。并且棧頂?shù)脑囟际莂pp的請求上下文和應(yīng)用上下文;
  • 之后,我們再在這個環(huán)境中嵌套app2的應(yīng)用上下文。當(dāng)進入app2的應(yīng)用上下文環(huán)境時,兩個上下文環(huán)境便隔離開來,此時再查看兩個棧的內(nèi)容,發(fā)現(xiàn)_app_ctx_stack中推入了app2的應(yīng)用上下文對象,并且棧頂指向它。這時在app2的應(yīng)用上下文環(huán)境中,current_app便會一直指向app2;
  • 當(dāng)離開app2的應(yīng)用上下文環(huán)境,_app_ctx_stack棧便會銷毀app2的應(yīng)用上下文對象。這時查看兩個棧的內(nèi)容,發(fā)現(xiàn)兩個棧中只有app的請求的請求上下文對象和應(yīng)用上下文對象。
  • ***,離開app的請求上下文環(huán)境后,兩個棧便會銷毀app的請求的請求上下文對象和應(yīng)用上下文對象,棧為空。

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

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

 
 
 
  1. # Flask v0.9 
  2.  
  3. _request_ctx_stack = LocalStack() 
  4.  
  5. _app_ctx_stack = LocalStack() 
  6.  
  7. current_app = LocalProxy(_find_app) 
  8.  
  9. request = LocalProxy(partial(_lookup_object, 'request')) 
  10.  
  11. session = LocalProxy(partial(_lookup_object, 'session')) 
  12.  
  13. g = LocalProxy(partial(_lookup_object, 'g')) 
  14.  
  15.   
  16.  
  17. # 輔助函數(shù) 
  18.  
  19. def _lookup_object(name): 
  20.  
  21.     top = _request_ctx_stack.top 
  22.  
  23.     if top is None: 
  24.  
  25.         raise RuntimeError('working outside of request context') 
  26.  
  27.     return getattr(top, name) 
  28.  
  29.   
  30.  
  31.   
  32.  
  33. def _find_app(): 
  34.  
  35.     top = _app_ctx_stack.top 
  36.  
  37.     if top is None: 
  38.  
  39.         raise RuntimeError('working outside of application context') 
  40.  
  41.     return top.app  

可以看出,F(xiàn)lask中使用的一些“全局變量”,包括current_app、request、session、g等都來自于上下文對象。其中current_app一直指向_app_ctx_stack棧頂?shù)摹皯?yīng)用上下文”對象,是對當(dāng)前應(yīng)用的引用。而request、session、g等一直指向_request_ctx_stack棧頂?shù)摹罢埱笊舷挛摹睂ο螅謩e引用請求上下文的request、session和g。不過,從 Flask 0.10 起,對象 g 存儲在應(yīng)用上下文中而不再是請求上下文中。

另外一個問題,在形成這些“全局變量”的時候,使用了werkzeug.local模塊的LocalProxy類。之所以要用該類,主要是為了動態(tài)地實現(xiàn)對棧頂元素的引用。如果不使用這個類,在生成上述“全局變量”的時候,它們因為指向棧頂元素,而棧頂元素此時為None,所以這些變量也會被設(shè)置為None常量。后續(xù)即使有上下文對象被推入棧中,相應(yīng)的“全局變量”也不會發(fā)生改變。為了動態(tài)地實現(xiàn)對棧頂元素的引用,這里必須使用werkzeug.local模塊的LocalProxy類。


新聞標(biāo)題:Flask中的請求上下文和應(yīng)用上下文
文章出自:http://m.5511xx.com/article/dhpsije.html