FLASK類
config 配置源碼解讀
構(gòu)建一個(gè)app應(yīng)用
示例代碼
from flask import Flask
import os
#定義一個(gè)配置類
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類的實(shí)例,以下是Flask類的與config相關(guān)的源碼
# 定義了一個(gè)默認(rèn)的配置字典
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)
繼續(xù)找這里返回的config_class,由下面代碼可以看出實(shí)際上返回了一個(gè)默認(rèn)配置的字典defaults,就是上面定義的那個(gè),這個(gè)時(shí)候的app.config就是一個(gè)字典default_config
app.config.form_object(config['dev'],這里config['dev']是一個(gè)字典,看from_object做了什么工作,這個(gè)函數(shù)從config['dev']這個(gè)字典里拿出配置的參數(shù),如果原來(lái)默認(rèn)字典里有的就修改,沒(méi)有的就添加.
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是一個(gè)字符串
obj = import_string(obj) #這里是可以從一個(gè)py文件導(dǎo)入的邏輯
for key in dir(obj): #這里的obj是一個(gè)字典
if key.isupper(): #配置字典里的配置項(xiàng)要大寫(xiě)的才能獲取到
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]
)