Inside Flask - flask.__init__.py 和核心组件
Inside Flask - flask.__init__.py 和核心组件
简单的示例
首先看看一个简单的示例。使用 Flask ,通常是从 flask 模块导入 Flask 、 request 等等组件。一个简单的示例如下:
from flask import Flask
app = Flask(__name__)
app.config.update(DEBUG=True)
@app.route('/')
@app.route('/index')
def index():
return '<h1>Hello, world!</h1>'
if __name__ == '__main__':
app.run()
这个简单示例只使用到 Flask 中的核心 Flask 对象,以及 Flask 的 route 机制,就能简单地提供一个显示 Hello, world! 字符串的 index 页面。其它更加复杂的结构和使用模式,都会基于类似的简单例子进行扩展,以满足一些特定场景的要求。
flask.__init__.py
除了 Flask 类,在 flask 模块里面还包含了其它 Flask 里的核心组件,打开这个源文件,可看到它里面包括:
abort
从
werkzeug.exceptions导入,调用时直接抛出异常。它的本质是werkzeug.exceptions里面的 Aborter() 对象。Aborter 使用工厂模式。其内部使用一个 dict 类型的
mapping成员变量来保存从 http 状态码到werkzeug.exceptions中定义的所有异常类之间的一个映射,然后通过一个 magic 方法__call__创建并抛出异常。所有的异常的基类为
HTTPException。它包含了两个基本的成员,code和description,分别表示中止时的 http 状态码和要返回给用户的信息。异常类定义完后,通过一个函数
_find_exceptions把所有在这里定义的异常类,放入到default_exceptions这个 dict 全局变量中。Abort 的初始化函数默认用default_exceptions作为mapping的值。abort支持的状态码包括 400 / 401 / 403 / 404 / 405 / 406 / 408 / 409 / 410 / 411 / 412 / 413 / 414 / 415 / 416 / 417 / 418 / 422 / 428 / 429 / 429 / 431 / 500 / 501 / 502 / 503 / 504/ 505 。使用示例:
@app.route('/_404')
def _404()
abort(404, 'Oops, 404.')
redirect
从
werkzeug.utils导入的重定向函数,通常与url_for结合使用。redirect生成一个Response对象,默认以 302 状态码返回响应。其响应的模板内容为(其中 escape 为 URL 转义函数):'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n'
'<title>Redirecting...</title>\n'
'<h1>Redirecting...</h1>\n'
'<p>You should be redirected automatically to target URL: '
'<a href="%s">%s</a>. If not click the link.' %
(escape(location), display_location), code, mimetype='text/html'
可见,当浏览器不支持 302 状态码自动重定向时,可通过点击响应的 html 中的链接进行跳转。
使用示例:
@app.route('/_redirect')
def _redirect()
return redirect(url_for('.index'))
Markup 和 escape
这两个都是从
Jinja2中导入,实际由另外一个模块markupsafe实现。Markup在markupsafe模块的__init__.py中,是对文本的一个封装,对字符串进行安全的转义,从而能方便地使用到 html 和 xml 中。Markup的实现过程中,使用到escape函数帮助转义。escape的实现其实很简单,就是把 html 中的预留字符转换为实体,代码如下:return Markup(text_type(s)
.replace('&', '&')
.replace('>', '>')
.replace('<', '<')
.replace("'", ''')
.replace('"', '"')
)
就是把
& > < ' "这几个字符转换为实体。使用示例:
Markup('<h1>%s<h1>') % '<h1>Hello, world!<h1>'
# 结果为 Markup('<h1><h1>Hello, world!<h1><h1>')
Flask Request Response
这 3 个类从
flask.app中导入(使用了当前相对位置导入from .app import ...)。Flask是整个 Flask 框架的核心类,它实现了 WSGI 的应用接口,提供路由、模板解析、日志、异常管理等等核心功能。Request和Response分别是对请求和响应的数据的包装,实际的代码在flask.wrappers中。它们继承werkzeug.wrappers里面的请求和响应类,根据 Flask 的设计概念的需要进行了扩展。后续深入分析这 3 个类
使用示例:
from flask import Flask, Response, request app = Flask(__name__) @app.route('/')
def index():
method = request.method
return Response('Request method: %s' % method) if __name__ == '__main__':
app.run()
辅助函数
url_forflashsend_file,send_from_directory等这堆辅助函数从
flask.helpers中导入,包括:url_for, flash, send_file, send_from_directory,
get_flashed_messages, get_template_attribute, make_response, safe_join,
stream_with_context
后续深入分析这些函数
上下文全局对象代理
current_appgrequest等这些对象从
flask.globals导入,在当前上下文环境中起作用,包括:current_app, g, request, session, _request_ctx_stack,
_app_ctx_stack
上下文模式是 web 框架中经常会使用到的模式,它表示当前会话、请求、应用的执行环境,是当前代码执行时所能使用到的变量、函数等等。不同的用户通常使用不同的上下文环境,通过相互隔离上下文环境提供一定的安全特性。上下文还与特定的实现技术有关,线程、协程会使用不同的实现方法,有时在不同的系统中会有需要注意的细节。
在实践中遇到的一些问题,特别是与 Flask 扩展有关的问题,很多是与上下文不对有关。
注意,
current_appgrequestsession均是LocalProxy,在运行时通过查找函数加载真正的对象。后续深入分析
flask.globals。上下文处理
has_request_contexthas_app_contextafter_this_requestcopy_current_request_context这些函数和组件从
flask.ctx导入,辅助处理上下文。在
flask.ctx中还定义了ApplcaitonContext和RequestContext两个上下文类。RequestContext包含请求时的信息,在请求开始时创建,在请求结束后清理。ApplicationContext包含应用的信息,绑定到当前的线程和协程上。当RequestContext发现没有ApplicationContext时,也会自动隐式创建一个(在RequestContext.push()中)。后续深入分析。
Module 和 Blueprint
分别从
flask.module和flask.blueprints导入,是 Flask 的扩展机制。根据Module中的注释,这种方式已经过时,被Blueprint取代。.. versionchanged:: 0.7
Modules were deprecated in favor for blueprints.
Blueprint是 Flask 中的主要模块化扩展方法。在编写大规模的应用时,可划分功能为多个Blueprint,每个Blueprint完成特定任务。使用示例:
task_bp = Blueprint('task')
app.register_blueprint(task_bp, url_prefix='/task')
后续深入分析。
视图渲染
render_templaterender_template_string这两个函数从
flask.templating导入,完成模板的渲染工作。使用示例:
# 模板文件 templates/index.html
<h1>{{ content }}</h1> # 视图渲染代码
@app.route('/')
def index():
return render_template('index.html', content='Hello, world!')
后续深入分析。
内部信号
signals_availabletemplate_renderedrequest_started等等Flask 提供信号机制,当某些操作发生时,通过信号方式通知其它代码,方便在这些操作发生时进行进一步处理。
现有的信号包括:
signals_available, template_rendered, request_started,
request_finished, got_request_exception, request_tearing_down,
appcontext_tearing_down, appcontext_pushed,
appcontext_popped, message_flashed
信号机制使用 blinker ,如果要自定义信号,需要额外安装这个模块。
json 支持
jsonify通过 json 方式进行响应。
使用示例:
return jsonify([1,2,3,4])
Session
Session 对象,实际类型为 'flask.sessions.SecureCookieSession',需要结合
SecureCookieSessionInterface一起使用。它可以用来定制 Flask 的 Session 保存方式,可放入到数据库或者 redis 里面,实现跨服务器的 session 共享。session 共享后,可通过服务器集群提升整个应用的访问处理能力。
官方文档有一个使用 redis 实现的 server-side session http://flask.pocoo.org/snippets/75/ 。
后续深入分析。
总结
以上已列出 Flask 里面的关键组件和概念,如果掌握这部分的概念,则使用 Flask 的过程中所遇到的问题基本能自己动手调试和解决。刚接触像上下文、信号机制、server-side session 等概念时会存在疑惑,这些概念需要理解源代码后,实际编程使用的过程中会慢慢熟悉。
后续的文章围绕上述概念展开,并探索 Flask 如何设计和实现这些概念,在整个实现过程中学习 Flask 的优秀设计。
Inside Flask - flask.__init__.py 和核心组件的更多相关文章
- Flask源码阅读-第二篇(flask\__init__.py)
源码: # -*- coding: utf-8 -*-""" flask ~~~~~ A microframework based on Werkzeug. It's e ...
- Inside Flask - flask 扩展加载过程
Inside Flask - flask 扩展加载过程 flask 扩展(插件)通常是以 flask_<扩展名字> 为扩展的 python 包名,而使用时,可用 import flask. ...
- Inside Flask - Flask 简介
Inside Flask - Flask 简介 前言 Flask 的设计目标是实现一个 wsgi 的微框架,其核心代码保持简单和可扩展性,很容易学习.对于有一定经验初学者而言,跟着例子和一些书的代码来 ...
- flask中manage.py的用法
flask中manage.py的用法#!/usr/bin/env pythonimport osfrom app import create_app, dbfrom app.models import ...
- Flask - Flask的蓝图(BluePrint)
目录 Flask - Flask的蓝图(BluePrint) 一. 初始Flask蓝图 进阶Flask蓝图 使用蓝图做一个增删改查 1.使用蓝图进行web应用搭建: 2.使用Flask蓝图,查看学生信 ...
- day92:flask:flask简介&基本运行&路由&HTTP请求和响应
目录 1.Flask简介 2.关于使用flask之前的准备 3.flask的基本运行 4.flask加载配置 5.传递路由参数(没有限定类型) 6.传递路由参数(通过路由转换器限定路由参数的类型) 7 ...
- [python][flask] Flask 入门(以一个博客后台为例)
目录 1.安装 1.1 创建虚拟环境 1.2 进入虚拟环境 1.3 安装 flask 2.上手 2.1 最小 Demo 2.2 基本知识 3.解构官网指导 Demo 3.1 克隆与代码架构分析 3.2 ...
- [python][flask] Flask 图片上传与下载例子(支持漂亮的拖拽上传)
目录 1.效果预览 2.新增逻辑概览 3.tuchuang.py 逻辑介绍 3.1 图片上传 3.2 图片合法检查 3.3 图片下载 4.__init__.py 逻辑介绍 5.upload.html ...
- python三大web框架Django,Flask,Flask,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架
Python几种主流框架 从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python We ...
随机推荐
- github配置
注册github账号: 准备秘钥文件: 认证: https://github.com 测试秘钥: 创建仓库: 执行下面命令创建git远程仓库: 添加一个two.txt文件:
- ajax无刷新获取php后台数据
$.ajax({ url:"result.php", //data:{"page":i}, dataType:"json", beforeS ...
- MySQL中的datetime与timestamp比较-------转载
原文地址http://database.51cto.com/art/200905/124240.htm MySQL中的datetime与timestamp比较 本文将通过实例比较MySQL中的date ...
- 三层架构实例 VB.NET版
三层实例 首先发现感慨,对于三成这块,用到都是一些面向对象的特征,尤其是对象的实例化.如果你不是很注意的话,那么,你就会一头雾水,就像我一样,慢慢的雾里看花,最后也是走出来的,不过用的事件是相当的. ...
- [转]禁用和启用链接(a元素|LinkButton)的js方法
本文转自:http://www.cnblogs.com/beiguren/archive/2010/05/24/1742926.html 在Asp.net中,有时候需要禁用掉一个a链接元素. 在服务器 ...
- RTO & RPO
作者:王文洋链接:https://www.zhihu.com/question/30753842/answer/49334210来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
- (6) 如何用Apache POI操作Excel文件-----POI-3.10的一个和注解(comment)相关的另外一个bug
如果POI-3.10往一个工作表(sheet)里面插入数据的话,需要注意了,其有一个不太被容易发现的bug. 被插入的工作表(sheet)里面的单元格没有包含任何的注解(comment)的时候,插入一 ...
- GDC 2016 神秘海域4中使用Substance制作Texture
TEXTURING UNCHARTED 4: A MATTER OF SUBSTANCE 原文链接 http://www.dualshockers.com/2016/03/16/amazing-unc ...
- 各种常用的JSON接口,开动你的大脑你就可以做出各种应用,值得收藏
各种常用的JSON接口,开动你的大脑你就可以做出各种应用,值得收藏 浏览:1412 发布日期:2014/01/27 分类:技术分享 这里为大家搜集了一些能够返回JSON格式的服务接口.部分需要用J ...
- HTML: Css引入的四種方式
哪四種?這裏簡單進行下總結 ①寫在 style 標籤中 <style type="text/css"> 這裏是css代碼... </style> ②外部引入 ...