flask中用了10个内置信号的地方分别是:
凡是有send的地方就用到了信号…
class AppContext(object):
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)
#1.这是一处:appcontext_pushed.send(self.app)
appcontext_pushed.send(self.app)
def pop(self, exc=_sentinel):
"""Pops the app context."""
try:
self._refcnt -= 1
if self._refcnt <= 0:
if exc is _sentinel:
exc = sys.exc_info()[1]
self.app.do_teardown_appcontext(exc)
finally:
rv = _app_ctx_stack.pop()
assert rv is self, 'Popped wrong app context. (%r instead of %r)' \
% (rv, self)
#2.这是一处:appcontext_popped.send(self.app)
appcontext_popped.send(self.app)
def full_dispatch_request(self):
self.try_trigger_before_first_request_functions()
try:
#3.这里一处:request_started.send(self)
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)
def finalize_request(self, rv, from_error_handler=False):
response = self.make_response(rv)
try:
response = self.process_response(response)
#4.这里一处:request_finished.send(self, 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
def do_teardown_request(self, exc=_sentinel):
if exc is _sentinel:
exc = sys.exc_info()[1]
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)
#5.这里一处:request_tearing_down.send(self, exc=exc)
request_tearing_down.send(self, exc=exc)
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)
#6.这里一处:appcontext_tearing_down.send(self, exc=exc)
appcontext_tearing_down.send(self, exc=exc)
def handle_exception(self, e):
exc_type, exc_value, tb = sys.exc_info()
#7.这里一处:got_request_exception.send(self, exception=e)
got_request_exception.send(self, exception=e)
handler = self._find_error_handler(InternalServerError())
def flash(message, category='message'):
flashes = session.get('_flashes', [])
flashes.append((category, message))
session['_flashes'] = flashes
#8.这里一处:message_flashed.send
message_flashed.send(current_app._get_current_object(),
message=message, category=category)
#还有两处是渲染页面时出现的
def _render(template, context, app):
"""Renders the template and fires the signal"""
#9.这是一处:before_render_template.send
before_render_template.send(app, template=template, context=context)
rv = template.render(context)
#10.这是一处template_rendered.send
template_rendered.send(app, template=template, context=context)
return rv
如果源码点不进去,可以这么处理:
app = Flask(__name__) # type:Flask
当然可以自定义信号:
from flask.signals import _signals
request_coped = _signals.signal('request-coped')
def func(*args,**kwargs):
print(args,kwargs)
request_coped.connect(func)
request_coped.send(sender='',a=1,b=2)
#打印结果{'sender':'','a':1,'b':2}
如果报错,则要安装blinker:
pip3 install blinker