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_for
flash
send_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_app
g
request
等这些对象从
flask.globals
导入,在当前上下文环境中起作用,包括:current_app, g, request, session, _request_ctx_stack,
_app_ctx_stack
上下文模式是 web 框架中经常会使用到的模式,它表示当前会话、请求、应用的执行环境,是当前代码执行时所能使用到的变量、函数等等。不同的用户通常使用不同的上下文环境,通过相互隔离上下文环境提供一定的安全特性。上下文还与特定的实现技术有关,线程、协程会使用不同的实现方法,有时在不同的系统中会有需要注意的细节。
在实践中遇到的一些问题,特别是与 Flask 扩展有关的问题,很多是与上下文不对有关。
注意,
current_app
g
request
session
均是LocalProxy
,在运行时通过查找函数加载真正的对象。后续深入分析
flask.globals
。上下文处理
has_request_context
has_app_context
after_this_request
copy_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_template
render_template_string
这两个函数从
flask.templating
导入,完成模板的渲染工作。使用示例:
# 模板文件 templates/index.html
<h1>{{ content }}</h1> # 视图渲染代码
@app.route('/')
def index():
return render_template('index.html', content='Hello, world!')
后续深入分析。
内部信号
signals_available
template_rendered
request_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 ...
随机推荐
- [转载] c++ cout 格式化输出浮点数、整数及格方法
C语言里可以用printf(),%f来实现浮点数的格式化输出,用cout呢...? 下面的方法是在网上找到的,如果各位有别的办法谢谢留下... iomanip.h是I/O流控制头文件,就像C里面的格式 ...
- WSUS更新服务器
http://windowsupdate.microsoft.com http://*.windowsupdate.microsoft.com https://*.windowsupdate.mi ...
- Apache Spark源码走读之17 -- 如何进行代码跟读
欢迎转载,转载请注明出处,徽沪一郎 概要 今天不谈Spark中什么复杂的技术实现,只稍为聊聊如何进行代码跟读.众所周知,Spark使用scala进行开发,由于scala有众多的语法糖,很多时候代码跟着 ...
- 每天学点GDB 11
为了跟踪glibc库中函数的执行,需要带有debug symbol的glibc, 如果是debian或者是基于debian的发行版本如ubuntu和linuxmint之类的,很简单执行如下指令安装即可 ...
- Windows远程桌面连接Mac OS X
Windows远程桌面连接Mac OS X 第一步:Mac OS X 10.5 已经增加支持了由VNC Viewer访问的功能,设置如下: 系统偏好设置-共享-勾选“屏幕共享”,然后在电脑设置 ...
- php防攻击方法
php防攻击方法 更多答案 请参考 @如何有效防止XSS攻击/AJAX跨域攻击 我说下防止非法用户的一些常用手段吧 1 前端的js验证: 我认为js验证只是一种用户体验的提升,对普通用户群体的简单 ...
- Moving in Unity
转自:http://angryant.com/2014/03/07/Moving-in-Unity/ ,详细描述了物体在unity中移动的几种方式,并且给出了代码描述,对加深对Unity理解很有帮助, ...
- Ruby--Array
--后面连接其它数组:[ARRAY].concat([OTHER ARRAY]) --排序:sort,进阶:sort_by{|obj| obj.[VALUE]} --随机获取:[ARRAY].samp ...
- Delphi指针的用法
DELPHI指针的使用 大家都认为,C语言之所以强大,以及其自由性,很大部分体现在其灵活的指针运用上.因此,说指针是C语言的灵魂,一点都不为过.同时,这种说法也让很多人产生误解,似乎只有C语言的指针才 ...
- 【转】如何使php的MD5与C#的MD5一致?
有c#生成MD5的代码如下: class CreateMD5 { static void Main(string[] args) { string source = "提问指南"; ...