Flask配置管理

目录

Flask在应用开始时载入配置,Flask对象使用config属性来操作配置,定义一些内置的配置变量,并支持添加自定义配置变量。

Config对象

Flask将配置保存在Config对象,从flask/config.py文件的定义中可以看到,Config对象就是一个字典。

class Config(dict):
    ...

只不过提供了多种填充内容的方法,包括从文件读取配置和从对象中获取配置等。
从环境变量指定的文件中读取配置

def from_envvar(self, variable_name, silent=False):

从文件中读取配置

def from_pyfile(self, filename, silent=False):

从对象中读取配置

def from_object(self, obj):

由此可见,Flask的Config只是对dict的简单扩展。
该文件中还有ConfigAttribute类,代表一个配置项。但Config对象使用dict而没有使用该对象,为什么要用一个特殊的配置项类呢?这与Flask对象中的配置项使用方式有关。

Flask类中的Config对象

Flask类中有config属性

self.config = self.make_config(instance_relative_config)

make_config方法使用默认配置参数生成Config对象

def make_config(self, instance_relative=False):
        root_path = self.root_path
        if instance_relative:
            root_path = self.instance_path
        return Config(root_path, self.default_config)

默认配置参数定义在default_config对象中

default_config = ImmutableDict({
    'DEBUG':                                False,
    'TESTING':                              False,
    # ... more ...
    'JSON_AS_ASCII':                        True,
    'JSON_SORT_KEYS':                       True,
    'JSONIFY_PRETTYPRINT_REGULAR':          True,
})

Flask的配置项保存在config对象中。Flask将一些常用的配置项转移到Flask对象中,可以直接使用Flask对象操作。

app.config['DEBUG'] = True

等同于

app.debug = True

而Flask类的debug属性就是一个ConfigAttribute类。下面看一下ConfigAttribute类的定义。

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

关键在__get__方法和__set__方法,当ConfigAttribute对象作为另一个对象的属性时,就变为该对象config字典属性中的一个键。
Flask类中定义

debug = ConfigAttribute('DEBUG')

debug就与config字典中的’DEBUG’键对应,从默认参数default_config中可以看到debug默认值为False.

后记

Flask使用一种简单的方式保存配置信息,将配置管理留给开发人员,让开发人员自己通过不同文件或不同对象来区别不同的运行环境。当前我正在考虑如何有效地区分开发和生产环境,并如何将两种环境有机结合到一起。Flask处理配置的方式可以考虑一下,将配置放在外部的某几个文件中,启动应用是按某种条件加载需要的配置文件。
开发和生产环境结合不仅仅是参数配置的问题,还有更深层次的东西有待研究。