Flask信号源码流程

1. appcontext_pushed = _signals.signal('appcontext-pushed'# 请求app上下文push时执行

return RequestContext(self, environ)
#############################################################
def push(self):
top = _request_ctx_stack.top
if top is not None and top.preserved:
top.pop(top._preserved_exc)
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)
app_ctx.push()
###########################################
def push(self):
"""Binds the app context to the current context."""
self._refcnt += 1
if hasattr(sys, 'exc_clear'):
sys.exc_clear()
_app_ctx_stack.push(self)
appcontext_pushed.send(self.app)

2. request_started = _signals.signal('request-started') #请求到来时执行

#在wsgi_app(self)方法中的def full_dispatch_request(self):方法 中  # 请求到来前执行 request_started.send(self)

    def full_dispatch_request(self):

        self.try_trigger_before_first_request_functions()
try:
request_started.send(self)
rv = self.preprocess_request()
if rv is None:
rv = self.dispatch_request()
except Exception as e:
rv = self.handle_user_exception(e)
return self.finalize_request(rv)

3. before_render_template = _signals.signal('before-render-template')  # 模板渲染前执行

def render_template(template_name_or_list, **context):
ctx = _app_ctx_stack.top
ctx.app.update_template_context(context)
return _render(ctx.app.jinja_env.get_or_select_template(template_name_or_list),
context, ctx.app)
def _render(template, context, app):

    before_render_template.send(app, template=template, context=context)
rv = template.render(context)
template_rendered.send(app, template=template, context=context)
return rv

4. template_rendered = _signals.signal('template-rendered')#模板渲染后执行

def _render(template, context, app):

    before_render_template.send(app, template=template, context=context)
rv = template.render(context)
template_rendered.send(app, template=template, context=context)
return rv

5. request_finished = _signals.signal('request-finished') # 请求结束后执行

第二步中的return
def finalize_request(self, rv, from_error_handler=False): response = self.make_response(rv)
try:
response = self.process_response(response)
request_finished.send(self, response=response)
except Exception:
if not from_error_handler:
raise
self.logger.exception('Request finalizing failed with an '
'error while handling an error')
return response

2/3/4/5或不执行 got_request_exception = _signals.signal('got-request-exception')    # 请求执行出现异常时执行

#在wsgi_app(self)方法中的response = self.handle_exception(e)方法 中 # 请求到来前执行got_request_exception.send(self, exception=e)
def handle_exception(self, e):

        exc_type, exc_value, tb = sys.exc_info()

        got_request_exception.send(self, exception=e)
handler = self._find_error_handler(InternalServerError())

6. request_tearing_down = _signals.signal('request-tearing-down')      # 请求执行完毕后自动执行(无论成功与否)

   #return RequestContext(self, environ)
 def pop(self, exc=_sentinel):
app_ctx = self._implicit_app_ctx_stack.pop() try:
clear_request = False
if not self._implicit_app_ctx_stack:
self.preserved = False
self._preserved_exc = None
if exc is _sentinel:
exc = sys.exc_info()[1]
self.app.do_teardown_request(exc) # If this interpreter supports clearing the exception information
# we do that now. This will only go into effect on Python 2.x,
# on 3.x it disappears automatically at the end of the exception
# stack.
if hasattr(sys, 'exc_clear'):
sys.exc_clear() request_close = getattr(self.request, 'close', None)
if request_close is not None:
request_close()
clear_request = True
finally:
rv = _request_ctx_stack.pop() # 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) assert rv is self, 'Popped wrong request context. ' \
'(%r instead of %r)' % (rv, self)
#self.app.do_teardown_request(exc)
def do_teardown_request(self, exc=_sentinel):
if exc is _sentinel:
exc = sys.exc_info()[1]
funcs = reversed(self.teardown_request_funcs.get(None, ()))
bp = _request_ctx_stack.top.request.blueprint
if bp is not None and bp in self.teardown_request_funcs:
funcs = chain(funcs, reversed(self.teardown_request_funcs[bp]))
for func in funcs:
func(exc)
request_tearing_down.send(self, exc=exc)

7. appcontext_tearing_down = _signals.signal('appcontext-tearing-down')# 请求上下文执行完毕后自动执行(无论成功与否)

    def do_teardown_appcontext(self, exc=_sentinel):

        if exc is _sentinel:
exc = sys.exc_info()[1]
for func in reversed(self.teardown_appcontext_funcs):
func(exc)
appcontext_tearing_down.send(self, exc=exc)

8. appcontext_popped = _signals.signal('appcontext-popped')            # 请求上下文pop时执行

上一篇:SQLite新建数据库及txt文件(CSV文件)导入


下一篇:sublime Text 2 配置以及 Python环境搭建