一、实例化补充

instance_path和instance_relative_config是配合来用的。

这两个参数是用来找配置文件的,当用app.config.from_pyfile('settings.py')这种方式导入配置文件的时候会用到

  1. from flask import Flask,request
  2. app = Flask(__name__,instance_path=None, instance_relative_config=True)
  3. app.config.from_pyfile('settings.py')
  4. # instsnce_path:#如果配置了instance_path,就会去找instance里面的文件
  5. # instance_relative_config: #如果设置为True,配置文件就找不到了,就会去找instance里面的settings.py
  6. app.open_session
  7. print(app.config.get("NNN"))
  8. @app.route('/index') # app.route('/index') f(index)
  9. def index():
  10. print(request)
  11. return "xx"
  12.  
  13. if __name__ == '__main__':
  14. app.__call__
  15. app.run()

如果设置了instance_releative_config = True,就找不着settings.py文件了,解决办法:就手动创建一个instance的文件夹

二、信号(blinker)

1、flask的内置信号

Flask框架中的信号基于blinker,其主要就是让开发者可是在flask请求过程中定制一些用户行为。说白了也就是flask在列表里面

预留了几个空列表,在里面存东西。信号通过发送通知来帮助你解耦应用。简言之,信号允许某个发送者通知接收者有事情发生了;、

  1. 10个信号:
  2. 2. request_started = _signals.signal('request-started') # 请求到来前执行
  3. 5. request_finished = _signals.signal('request-finished') # 请求结束后执行
  4.  
  5. 3. before_render_template = _signals.signal('before-render-template') # 模板渲染前执行
  6. 4. template_rendered = _signals.signal('template-rendered') # 模板渲染后执行
  7.  
  8. 执行2/3/4/5或不执行时出现异常 got_request_exception = _signals.signal('got-request-exception') # 请求执行出现异常时执行
  9.  
  10. 6. request_tearing_down = _signals.signal('request-tearing-down') # 请求执行完毕后自动执行(无论成功与否)
  11. 7. appcontext_tearing_down = _signals.signal('appcontext-tearing-down')# 请求上下文执行完毕后自动执行(无论成功与否)
  12.  
  13. 1. appcontext_pushed = _signals.signal('appcontext-pushed') # 请求app上下文push时执行
  14.  
  15. 8. appcontext_popped = _signals.signal('appcontext-popped') # 请求上下文pop时执行
  16.  
  17. message_flashed = _signals.signal('message-flashed') # 调用flask在其中添加数据时,自动触发

问题1:特殊的装饰器(@app.before_first_request ;@app.before_request ; @app.after_request和信号有什么区别?

   -  触发信号是没有返回值的,写不写返回值都无所谓

   -  特殊的装饰器对返回值是有意义的,当before_request有返回值时就不会执行后续视图函数了,没有返回值的时候才会执行后续函数,而after_request必须有返回值

         所以特殊装饰器的功能比信号的功能强大

问题2:通过信号可以做权限吗?

   - 本身是做不了的,要想做得用其他的机制配合着来使用,这样做的话会闲的很麻烦,所以我们选择中间件来做

问题3:信号用于做什么呢?

   - 只做一些自定义的操作,而且没有返回值

    - 降低代码之间的耦合

flask内置信号源码详细

  1. class Flask(_PackageBoundObject):
  2.  
  3. def full_dispatch_request(self):
  4.  
  5. self.try_trigger_before_first_request_functions()
  6. try:
  7. # ############### 触发request_started 信号 ###############
  8. request_started.send(self)
  9. rv = self.preprocess_request()
  10. if rv is None:
  11. rv = self.dispatch_request()
  12. except Exception as e:
  13. rv = self.handle_user_exception(e)
  14. response = self.make_response(rv)
  15. response = self.process_response(response)
  16.  
  17. # ############### request_finished 信号 ###############
  18. request_finished.send(self, response=response)
  19. return response
  20.  
  21. def wsgi_app(self, environ, start_response):
  22.  
  23. ctx = self.request_context(environ)
  24. ctx.push()
  25. error = None
  26. try:
  27. try:
  28. response = self.full_dispatch_request()
  29. except Exception as e:
  30. error = e
  31. response = self.make_response(self.handle_exception(e))
  32. return response(environ, start_response)
  33. finally:
  34. if self.should_ignore_error(error):
  35. error = None
  36. ctx.auto_pop(error)

同上

  1. def render_template(template_name_or_list, **context):
  2. """Renders a template from the template folder with the given
  3. context.
  4.  
  5. :param template_name_or_list: the name of the template to be
  6. rendered, or an iterable with template names
  7. the first one existing will be rendered
  8. :param context: the variables that should be available in the
  9. context of the template.
  10. """
  11. ctx = _app_ctx_stack.top
  12. ctx.app.update_template_context(context)
  13. return _render(ctx.app.jinja_env.get_or_select_template(template_name_or_list),
  14. context, ctx.app)
  15.  
  16. def _render(template, context, app):
  17. """Renders the template and fires the signal"""
  18.  
  19. # ############### before_render_template 信号 ###############
  20. before_render_template.send(app, template=template, context=context)
  21. rv = template.render(context)
  22.  
  23. # ############### template_rendered 信号 ###############
  24. template_rendered.send(app, template=template, context=context)
  25. return rv

同上

  1. class Flask(_PackageBoundObject):
  2.  
  3. def handle_exception(self, e):
  4.  
  5. exc_type, exc_value, tb = sys.exc_info()
  6.  
  7. # ############### got_request_exception 信号 ###############
  8. got_request_exception.send(self, exception=e)
  9. handler = self._find_error_handler(InternalServerError())
  10.  
  11. if self.propagate_exceptions:
  12. # if we want to repropagate the exception, we can attempt to
  13. # raise it with the whole traceback in case we can do that
  14. # (the function was actually called from the except part)
  15. # otherwise, we just raise the error again
  16. if exc_value is e:
  17. reraise(exc_type, exc_value, tb)
  18. else:
  19. raise e
  20.  
  21. self.log_exception((exc_type, exc_value, tb))
  22. if handler is None:
  23. return InternalServerError()
  24. return handler(e)
  25.  
  26. def wsgi_app(self, environ, start_response):
  27.  
  28. ctx = self.request_context(environ)
  29. ctx.push()
  30. error = None
  31. try:
  32. try:
  33. response = self.full_dispatch_request()
  34. except Exception as e:
  35. error = e
  36. # 这里这里这里这里这里这里这里这里这里这里这里这里 #
  37. response = self.make_response(self.handle_exception(e))
  38. return response(environ, start_response)
  39. finally:
  40. if self.should_ignore_error(error):
  41. error = None
  42. ctx.auto_pop(error)
  1. class AppContext(object):
  2. def push(self):
  3. """Binds the app context to the current context."""
  4. self._refcnt += 1
  5. if hasattr(sys, 'exc_clear'):
  6. sys.exc_clear()
  7. _app_ctx_stack.push(self)
  8. # ############## 触发 appcontext_pushed 信号 ##############
  9. appcontext_pushed.send(self.app)
  10.  
  11. def pop(self, exc=_sentinel):
  12. """Pops the app context."""
  13. try:
  14. self._refcnt -= 1
  15. if self._refcnt <= 0:
  16. if exc is _sentinel:
  17. exc = sys.exc_info()[1]
  18. # ############## 触发 appcontext_tearing_down 信号 ##############
  19. self.app.do_teardown_appcontext(exc)
  20. finally:
  21. rv = _app_ctx_stack.pop()
  22. assert rv is self, 'Popped wrong app context. (%r instead of %r)' \
  23. % (rv, self)
  24.  
  25. # ############## 触发 appcontext_popped 信号 ##############
  26. appcontext_popped.send(self.app)
  27.  
  28. class RequestContext(object):
  29. def push(self):
  30. top = _request_ctx_stack.top
  31. if top is not None and top.preserved:
  32. top.pop(top._preserved_exc)
  33.  
  34. app_ctx = _app_ctx_stack.top
  35. if app_ctx is None or app_ctx.app != self.app:
  36.  
  37. # ####################################################
  38. app_ctx = self.app.app_context()
  39. app_ctx.push()
  40. self._implicit_app_ctx_stack.append(app_ctx)
  41. else:
  42. self._implicit_app_ctx_stack.append(None)
  43.  
  44. if hasattr(sys, 'exc_clear'):
  45. sys.exc_clear()
  46.  
  47. _request_ctx_stack.push(self)
  48.  
  49. # Open the session at the moment that the request context is
  50. # available. This allows a custom open_session method to use the
  51. # request context (e.g. code that access database information
  52. # stored on `g` instead of the appcontext).
  53. self.session = self.app.open_session(self.request)
  54. if self.session is None:
  55. self.session = self.app.make_null_session()
  56.  
  57. class Flask(_PackageBoundObject):
  58.  
  59. def wsgi_app(self, environ, start_response):
  60.  
  61. ctx = self.request_context(environ)
  62. ctx.push()
  63. error = None
  64. try:
  65. try:
  66. response = self.full_dispatch_request()
  67. except Exception as e:
  68. error = e
  69. response = self.make_response(self.handle_exception(e))
  70. return response(environ, start_response)
  71. finally:
  72. if self.should_ignore_error(error):
  73. error = None
  74. ctx.auto_pop(error)
  75.  
  76. def pop(self, exc=_sentinel):
  77. app_ctx = self._implicit_app_ctx_stack.pop()
  78.  
  79. try:
  80. clear_request = False
  81. if not self._implicit_app_ctx_stack:
  82. self.preserved = False
  83. self._preserved_exc = None
  84. if exc is _sentinel:
  85. exc = sys.exc_info()[1]
  86.  
  87. # ################## 触发 request_tearing_down 信号 ##################
  88. self.app.do_teardown_request(exc)
  89.  
  90. # If this interpreter supports clearing the exception information
  91. # we do that now. This will only go into effect on Python 2.x,
  92. # on 3.x it disappears automatically at the end of the exception
  93. # stack.
  94. if hasattr(sys, 'exc_clear'):
  95. sys.exc_clear()
  96.  
  97. request_close = getattr(self.request, 'close', None)
  98. if request_close is not None:
  99. request_close()
  100. clear_request = True
  101. finally:
  102. rv = _request_ctx_stack.pop()
  103.  
  104. # get rid of circular dependencies at the end of the request
  105. # so that we don't require the GC to be active.
  106. if clear_request:
  107. rv.request.environ['werkzeug.request'] = None
  108.  
  109. # Get rid of the app as well if necessary.
  110. if app_ctx is not None:
  111. # ####################################################
  112. app_ctx.pop(exc)
  113.  
  114. assert rv is self, 'Popped wrong request context. ' \
  115. '(%r instead of %r)' % (rv, self)
  116.  
  117. def auto_pop(self, exc):
  118. if self.request.environ.get('flask._preserve_context') or \
  119. (exc is not None and self.app.preserve_context_on_exception):
  120. self.preserved = True
  121. self._preserved_exc = exc
  122. else:
  123. self.pop(exc)
  1. def flash(message, category='message'):
  2. """Flashes a message to the next request. In order to remove the
  3. flashed message from the session and to display it to the user,
  4. the template has to call :func:`get_flashed_messages`.
  5.  
  6. .. versionchanged:: 0.3
  7. `category` parameter added.
  8.  
  9. :param message: the message to be flashed.
  10. :param category: the category for the message. The following values
  11. are recommended: ``'message'`` for any kind of message,
  12. ``'error'`` for errors, ``'info'`` for information
  13. messages and ``'warning'`` for warnings. However any
  14. kind of string can be used as category.
  15. """
  16. # Original implementation:
  17. #
  18. # session.setdefault('_flashes', []).append((category, message))
  19. #
  20. # This assumed that changes made to mutable structures in the session are
  21. # are always in sync with the session object, which is not true for session
  22. # implementations that use external storage for keeping their keys/values.
  23. flashes = session.get('_flashes', [])
  24. flashes.append((category, message))
  25. session['_flashes'] = flashes
  26.  
  27. # ############### 触发 message_flashed 信号 ###############
  28. message_flashed.send(current_app._get_current_object(),
  29. message=message, category=category)

2、自定义信号(Blinker的使用)

  第一步:创建信号

  第二步:将函数注册到信号中: 添加到这个列表

  第三步: 发送信号

  第四步:运行

具体实现:可参考flask源码,写一个自定义信号

  1. from flask import Flask,flash
  2. from flask.signals import _signals
  3. app = Flask(__name__)
  4.  
  5. xinhao = _signals.signal("xinhao")#创建信号
  6. #定义函数
  7. def wahaha(*args,**kwargs):
  8. print("娃哈哈",args,kwargs)
  9.  
  10. def sww(*args,**kwargs):
  11. print("爽歪歪",args,kwargs)
  12. # 将函数注册到信号中,添加到这个列表
  13. xinhao.connect(wahaha)
  14. xinhao.connect(sww)
  15.  
  16. @app.route("/zzz")
  17. def zzz():
  18. xinhao.send(sender='xxx',a1=123,a2=456) #触发这个信号,执行注册到列表中的所有函数,这里的参数个上面函数的参数一致
  19. return "发送信号成功"
  20.  
  21. if __name__ == '__main__':
  22. app.run(debug=True)
  23.  
  24. #打印结果
  25. # 娃哈哈 (None,) {'sender': 'xxx', 'a1': 123, 'a2': 456}
  26. # 爽歪歪 (None,) {'sender': 'xxx', 'a1': 123, 'a2': 456}

三、chain模块简单的测试

  1. v1 = [11,22,33,44]
  2. v2 = [1,4,7,5]
  3. from itertools import chain
  4. ff = []
  5. for i in chain(v1,v2): #chain会把两个列表连接在一块
  6. ff.append(i)
  7. print(ff) #[11, 22, 33, 44, 1, 4, 7, 5]

Flask系列(六)Flask实例化补充及信号的更多相关文章

  1. Flask系列(二)Flask基础

    知识点回顾 1.flask依赖wsgi,实现wsgi的模块:wsgiref(django),werkzeug(flask),uwsgi(上线) 2.实例化Flask对象,里面是有参数的 app = F ...

  2. flask系列六之模型分文件

    1.分开models的目的:为了让代码更加方便的管理. 2.如何解决循环引用:把db放在一个单独的文件中,切断循环引用的线条就可以了. (1)避免循环引用 解决循环引用 主文件:main.py fro ...

  3. Flask系列06--(中间件)Flask的特殊装饰器 before_request,after_request, errorhandler

    一.使用 Flask中的特殊装饰器(中间件)方法常用的有三个 @app.before_request # 在请求进入视图函数之前 @app.after_request # 在请求结束视图函数之后 响应 ...

  4. Flask系列(四)Flask实现简单页面登陆

    from flask import Flask,render_template,request,redirect,session app = Flask(__name__,template_folde ...

  5. Flask系列(五)Flask实现分页

    一.flask分页组件 from urllib.parse import urlencode,quote,unquote class Pagination(object): ""& ...

  6. 补充的flask实例化参数以及信号

    一.实例化补充 instance_path和instance_relative_config是配合来用的.这两个参数是用来找配置文件的,当用app.config.from_pyfile('settin ...

  7. flask实例化参数以及信号

    一.实例化补充 instance_path和instance_relative_config是配合来用的.这两个参数是用来找配置文件的,当用app.config.from_pyfile('settin ...

  8. Flask 系列之 部署发布

    说明 操作系统:Windows 10 Python 版本:3.7x 虚拟环境管理器:virtualenv 代码编辑器:VS Code 实验目标 通过 Windows 的 WSL,将我们的项目网站部署到 ...

  9. Flask系列之源码分析(一)

    目录: 涉及知识点 Flask框架原理 简单示例 路由系统原理源码分析 请求流程简单源码分析 响应流程简单源码分析 session简单源码分析 涉及知识点 1.装饰器 闭包思想 def wapper( ...

随机推荐

  1. oracle 无效索引

    错误信息:ORA-01502: index 'VOX_ID' or partition of such index is in unusable state 原因:将表的表空间做了更改,导致索引失效. ...

  2. mybatise 动态sql

    1. <if><choose> 动态sql 相当 <if> Java if  满足多个条件  <choose> <when>    java ...

  3. [dubbo] dubbo No provider available for the service

    com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method queryTemplate in the service com.x.a ...

  4. fildder教程

    转载地址:写得很不错的fildder教程   http://kb.cnblogs.com/page/130367/ Fiddler的基本介绍 Fiddler的官方网站:  www.fiddler2.c ...

  5. css图片宽高相等设置

    <div class="image-header"> <img src="demo.jpg"> </div> .image- ...

  6. Android之HttpPost与HttpGet使用

    一)HttpGet :doGet()方法 //doGet():将参数的键值对附加在url后面来传递 public String getResultForHttpGet(String name,Stri ...

  7. Python2 与 Python3 区别

    print 用法不同:在 Python2 中,print 用法为 print "Hello World"在 Python3 中,print 用法为 print("Hell ...

  8. PHP5 session 详解【经典】

    原文:http://www.pkwind.com/php5-session-xiang-jie-jing-dian http协议是WEB服务器与客户端 (浏览器)相互通信的协议,它是一种无状态协议.所 ...

  9. C# Distinct使用,支持对象的相等比较

    官网Enumerable.Distinct https://msdn.microsoft.com/zh-cn/library/bb338049.aspx CSDN中作者oriency755 关于Dis ...

  10. python初学总结(二)

    (1)字典 字典是一种映射关系:键(key),值(value),key-value对 创建字典的方式:直接创建和利用dict函数创建 >>> aInfo = {'Wangdachui ...