# 这里会调用Flask.__call__(self, environ, start_response)
app = Flask(__name__)
if __name__=='__main__':
app.run()
def__call__(self, environ, start_response):"""Shortcut for :attr:`wsgi_app`."""return self.wsgi_app(environ, start_response)
# 接着返回一个对象,这里去执行,我们看下这个:defwsgi_app(self, environ, start_response):# 关键代码
ctx = self.request_context(environ)
#返回的上下文对象放到哪里去了呢?我们看下push方法:
ctx.push()
# 处理请求:try:
#这里去分发request,处理requestfinally:
#当请求结束:
ctx.auto_pop(error)
#我们看下ctx = self.request_context(environ)做了什么?defrequest_context(self, environ):#返回了请求的上下文对象,那么ctx 代表请求的上下文对象return RequestContext(self, environ)
#ctx.push()调用的push方法classRequestContext(object):defpush(self):# 这里将自己加入了_request_ctx_stack,#那么_request_ctx_stack是个什么鬼?
_request_ctx_stack.push(self)
#在globals.py文件中可以看到:
_request_ctx_stack = LocalStack()
#那么LocalStack 中的都有什么呢?classLocalStack(object):def__init__(self):#接着我们看下local是个啥?
self._local = Local()
defpush(self, obj):# push方法的作用将新的item压栈,这里看到self._local"""Pushes a new item to the stack"""
rv = getattr(self._local, 'stack', None)
if rv isNone:
#现在的字典是这样的:{'当前线程的唯一标识':{'stack':[]}}
self._local.stack = rv = []
# 请求进来将请求上下文RequestContext加入到列表中:
rv.append(obj)
return rv
#接着我们看下local是个啥?self._local = Local()classLocal(object):def__init__(self):# 看这是创建了空字典
object.__setattr__(self, '__storage__', {})
#这是干什么的呢?看下get_ident
object.__setattr__(self, '__ident_func__', get_ident)
def__setattr__(self, name, value):#触发get_ident的运行
ident = self.__ident_func__()
storage = self.__storage__
try:
#那么这句话构造了一个字典,key便是当前线程的标识,代表了当前线程。形如:#{'当前线程标识':{name:value}},那么回去我们再看上面:self._local.stack = rv = []
storage[ident][name] = value
except KeyError:
storage[ident] = {name: value}
#get_ident 是干什么用的呢?defget_ident():# real signature unknown; restored from __doc__"""
get_ident() -> integer
#翻译一下:返回一个能唯一标识当前线程和其它共存线程的非零integer!!!
Return a non-zero integer that uniquely identifies the current thread
amongst other threads that exist simultaneously /saɪmlˈteɪniəsli/.
This may be used to identify per-thread resources.
Even though on some platforms threads identities may appear to be
allocated consecutive numbers starting at 1, this behavior should not
be relied upon, and the number should be seen purely as a magic cookie.
A thread's identity may be reused for another thread after it exits.
"""return0#当请求结束,执行ctx.auto_pop(error)defauto_pop(self, exc):if self.request.environ.get('flask._preserve_context') or \
(exc isnotNoneand self.app.preserve_context_on_exception):
self.preserved = True
self._preserved_exc = exc
else:
# 直接将当前的请求上下文pop掉
self.pop(exc)
#最终调用self.pop(exc):defpop(self, exc=_sentinel):#翻译一下:将请求上下文弹栈,并解绑!"""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.