FLASK类
config 配置源码解读
构建一个app应用
示例代码
from flask import Flask
import os
#定义一个配置类
class development():
SECRET_KEY = os.environ.get('SECRET_KEY') or os.urandom(24)
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
SQLALCHEMY_TRACK_MODIFICATIONS = True
#把配置类放到字典里
config = {
"dev": development
}
app = Flask(__name__)
app.config.from_object(config['dev'])
print(app.config)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
app是Flask类的实例,以下是Flask类的与config相关的源码
# 定义了一个默认的配置字典
default_config = ImmutableDict(
{
...
"SECRET_KEY": None,
...
}
)
class Flask(_PackageBoundObject):
...
self.config = self.make_config(instance_relative_config)
# app的config 由make_config方法处理
...
def make_config(self, instance_relative=False):
...
root_path = self.root_path #这里的root_path 是None
if instance_relative: # 这里是False
root_path = self.instance_path
defaults = dict(self.default_config)
defaults["ENV"] = get_env()
defaults["DEBUG"] = get_debug_flag()
return self.config_class(root_path, defaults)
继续找这里返回的config_class,由下面代码可以看出实际上返回了一个默认配置的字典defaults,就是上面定义的那个,这个时候的app.config就是一个字典default_config
app.config.form_object(config['dev'],这里config['dev']是一个字典,看from_object做了什么工作,这个函数从config['dev']这个字典里拿出配置的参数,如果原来默认字典里有的就修改,没有的就添加.
config_class = Config
class Config(dict):
def __init__(self, root_path, defaults=None):
dict.__init__(self, defaults or {})
self.root_path = root_path
def from_object(self, obj):
if isinstance(obj, string_types): #这里的obj是一个字符串
obj = import_string(obj) #这里是可以从一个py文件导入的逻辑
for key in dir(obj): #这里的obj是一个字典
if key.isupper(): #配置字典里的配置项要大写的才能获取到
self[key] = getattr(obj, key)
def get_env():
"""Get the environment the app is running in, indicated by the
:envvar:`FLASK_ENV` environment variable. The default is
``'production'``.
"""
return os.environ.get("FLASK_ENV") or "production"
utils里的import_string方法
def import_string(import_name, silent=False):
# force the import name to automatically convert to strings
# __import__ is not able to handle unicode strings in the fromlist
# if the module is a package
import_name = str(import_name).replace(":", ".")
try:
try:
__import__(import_name)
except ImportError:
if "." not in import_name:
raise
else:
return sys.modules[import_name]
module_name, obj_name = import_name.rsplit(".", 1)
module = __import__(module_name, globals(), locals(), [obj_name])
try:
return getattr(module, obj_name)
except AttributeError as e:
raise ImportError(e)
except ImportError as e:
if not silent:
reraise(
ImportStringError, ImportStringError(import_name, e), sys.exc_info()[2]
)