Inside Flask - 配置的实现
Inside Flask - 配置的实现
flask 的配置对象 app.config 本身使用很简单,无非就是以字典的形式使用,而它的实现,本身就是以字典的形式的。
在 flask/config.py 文件中,包含了 flask 配置的实现代码,就两个类 ConfigAttribute 和 Config 。
ConfigAttribute 表示一个配置属性,它的代码只有简单几行,但由于使用了 descriptor 模式,对 python 不熟悉的人不容易理解。先看看 descriptor 是个什么东西。
descriptor 属于 python 元编程方面的概念(即是对编程的编程,%>_<%),本质上是提供一种编程的协议,也就是制定某种框架供业务编程时使用(像 C# / java 的反射也属于元编程范畴)。由于动态语言的特性,元编程在 python 里面实现起来非常简单。作为 descriptor 的对象,它提供的描述属性的协议,它需要实现 __get__ __set__ 和 __delete__,来描述某个某个对象(被描述对象)应该如何获取数据、设置数据和删除对象。
现在再来看看 ConfigAttribute 类 ::
class ConfigAttribute(object):
"""Makes an attribute forward to the config"""
def __init__(self, name, get_converter=None):
self.__name__ = name
self.get_converter = get_converter
def __get__(self, obj, type=None):
if obj is None:
return self
rv = obj.config[self.__name__]
if self.get_converter is not None:
rv = self.get_converter(rv)
return rv
def __set__(self, obj, value):
obj.config[self.__name__] = value
这里的约定是定义 ConfigAttribute 的对象里,应该包含一个 config 字典,然后取值或设置值时,改为取或设置 config 中对应的 key 的值(在 flask 的 Flask 类里面,包含 config,类型就是接下来要看的 Config 类)。
Config 类继承 dict ,就是一个保存了 ConfigAttribute 的字典 ::
class Config(dict):
...
同时,Config 类提供几个加载配置的方法,分别是 ::
from_envvar(...) # 从环境变量读取所要加载的 py 文件路径,然后用 from_pyfile 加载
from_pyfile(...) # 从 py 文件中加载文件,然后用 from_object 加载
from_object(...) # 从对象加载,把 dir(obj) 中,名字是大写的数据载入到 self
from_json(...) # 从 json 文件加载,然后调用 from_mapping 加载
from_mapping(...) # 从多个字典,或 **kwargs 形式的参数,且名字是大写的数据加载到 self
在加载文件时,可以使用该 flask 应用内的相对路径(见下文),或者是使用绝对路径,代码在处理时,都用 ::
filename = os.path.join(self.root_path, filename)
当文件为相对路径时,就会用当前 flask app 的路径结合相对路径来定位文件。
Config 中的配置有个 namespace 的概念,通过下划线对参数进行分类,方便一次获取多个配置项 ::
def get_namespace(self, namespace, lowercase=True, trim_namespace=True):
"""Returns a dictionary containing a subset of configuration options
that match the specified namespace/prefix. Example usage::
app.config['IMAGE_STORE_TYPE'] = 'fs'
app.config['IMAGE_STORE_PATH'] = '/var/app/images'
app.config['IMAGE_STORE_BASE_URL'] = 'http://img.website.com'
image_store_config = app.config.get_namespace('IMAGE_STORE_')
The resulting dictionary `image_store_config` would look like::
{
'type': 'fs',
'path': '/var/app/images',
'base_url': 'http://img.website.com'
}
从源代码层面看,这里有几点是需要注意的:(1)最后起作用的 from_object 和 from_mapping,其它几个是做预处理;(2)配置的 key 应该是大写的,然后以下划线做分隔
OK,现在看看 flask 里面怎样使用配置。
首先在 flask/app.py 里面,Flask 类代码中包含了一个 config_class ,它默认就是 Config 类。然后 config 属性通过 make_config 生成 ::
self.config = self.make_config(instance_relative_config)
而 make_config 的代码如下 ::
def make_config(self, instance_relative=False):
"""Used to create the config attribute by the Flask constructor.
The `instance_relative` parameter is passed in from the constructor
of Flask (there named `instance_relative_config`) and indicates if
the config should be relative to the instance path or the root path
of the application.
.. versionadded:: 0.8
"""
root_path = self.root_path
if instance_relative:
root_path = self.instance_path
return self.config_class(root_path, self.default_config)
这里有个概念是 instance_relative 的配置,即与实例相关的配置。如果在一个应用里面用到了几个 flask app ,并且这些 app 的配置不一样时,就要用到实例相关的配置,将当前的 root_path 设置为初始化 flask app 时的参数 instance_path(可自由设置)。
self.default_config 是一个默认配置的字典,如下 ::
default_config = ImmutableDict({
'DEBUG': get_debug_flag(default=False),
'TESTING': False,
'PROPAGATE_EXCEPTIONS': None,
'PRESERVE_CONTEXT_ON_EXCEPTION': None,
'SECRET_KEY': None,
'PERMANENT_SESSION_LIFETIME': timedelta(days=31),
'USE_X_SENDFILE': False,
...
})
而使用到 ConfigAttribute 的几个代码如下 ::
debug = ConfigAttribute('DEBUG')
...
testing = ConfigAttribute('TESTING')
...
flask 设置完配置项后,用户可根据自己的需要,用操作字典的方式修改、更新配置 ::
app.config.update({'DEBUG': False})
app.config.from_object(config_obj)
app.config.setdefault('DEBUG', False)
...
Inside Flask - 配置的实现的更多相关文章
- Inside Flask - json 处理
Inside Flask - json 处理 在处理 web api 时,json 是非常好用的数据交换格式,它结构简单,基本上各种主流的编程语言都有良好的支持工具. flask 中处理 json 时 ...
- Inside Flask - app.py - 2
Inside Flask - app.py - 2 Flask 初始化参数 Flass 类是 Flask 框架的核心,一个 flask 对象处理视图函数注册.URL规则.模板配置.参数设置等等. 一般 ...
- Inside Flask - app.py - 1
Inside Flask - app.py - 1 除 werkzeug 和 jinja2 等依赖库外,app.py 是在 Flask 的 __init__.py 中导入的第一个 Flask 自身的模 ...
- Inside Flask - signal 信号机制
Inside Flask - signal 信号机制 singal 在平常的 flask web 开发过程中较少接触到,但对于使用 flask 进行框架级别的开发时,则必须了解相关的工作机制.flas ...
- Inside Flask - globals 全局变量(对象代理)
Inside Flask - globals 全局变量(对象代理) 框架是一个容器,在框架内编程,一般是要遵守框架的约定和使用模式.通常这样的模式是 IoC,即由框架调用用户的代码,而不是用户调用框架 ...
- Inside Flask - flask 扩展加载过程
Inside Flask - flask 扩展加载过程 flask 扩展(插件)通常是以 flask_<扩展名字> 为扩展的 python 包名,而使用时,可用 import flask. ...
- Inside Flask - flask.__init__.py 和核心组件
Inside Flask - flask.__init__.py 和核心组件 简单的示例 首先看看一个简单的示例.使用 Flask ,通常是从 flask 模块导入 Flask . request 等 ...
- Inside Flask - Flask 简介
Inside Flask - Flask 简介 前言 Flask 的设计目标是实现一个 wsgi 的微框架,其核心代码保持简单和可扩展性,很容易学习.对于有一定经验初学者而言,跟着例子和一些书的代码来 ...
- 第八篇 Flask配置
Flask 是一个非常灵活且小而精的web框架 , 那么灵活性从什么地方体现呢? 列如 Flask配置,这个东西怎么用呢? 它能给我们带来怎么样的方便呢? app配置 首先展示一下: from fl ...
随机推荐
- Android PhoneGap 利用 Activity 实现 CordovaInterface
1.修改main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns ...
- ACM: Racing Gems - 最长递增序列
Racing Gems You are playing a racing game. Your character starts at the x axis (y = 0) and procee ...
- 【BZOJ】1086: [SCOI2005]王室联邦
http://www.lydsy.com/JudgeOnline/problem.php?id=1086 题意:n个点的树,要求分块,使得每一块的大小在[b, 3b]内且块与某个点形成的块是连通的(某 ...
- My Notepad
I have spent near more two weeks to write this Notepad application. At this moment, I want to share ...
- LightOJ 1245 数学题,找规律
1.LightOJ 1245 Harmonic Number (II) 数学题 2.总结:看了题解,很严谨,但又确实恶心的题 题意:求n/1+n/2+....+n/n,n<=2^31. ...
- 深入浅出 - Android系统移植与平台开发(八)- HAL Stub框架分析
作者:唐老师,华清远见嵌入式学院讲师. 1. HAL Stub框架分析 HAL stub的框架比较简单,三个结构体.两个常量.一个函数,简称321架构,它的定义在:@hardware/libhardw ...
- Java_Java中动态加载jar文件和class文件
转自:http://blog.csdn.net/mousebaby808/article/details/31788325 概述 诸如tomcat这样的服务器,在启动的时候会加载应用程序中lib目录下 ...
- springmvc入门基础之注解和参数传递
一.SpringMVC注解入门 1. 创建web项目2. 在springmvc的配置文件中指定注解驱动,配置扫描器 <!-- mvc的注解驱动 --> <mvc:annotation ...
- 二 、打开地图《苹果iOS实例编程入门教程》
该app为应用的功能为给你的iPhone打开google地图有效地址连接 现版本 SDK 8.4 Xcode 运行Xcode 选择 Create a new Xcode project ->Si ...
- 分模块创建maven项目(一)
maven是一个项目构建和管理的工具. 我们可以通过maven仓库可以实现管理构建(主要是JAR还包括:WAR,ZIP,POM等等). 我们可以通过maven插件可以实现编译源代.产生Javadoc文 ...