python-flask-配置文件的源码分析
方式一:app.config['xx'] = 'xxx'
源码分析:
#第1步:
class Flask(_PackageBoundObject):
self.config = self.make_config(instance_relative_config)
#第2步:
def make_config(self, instance_relative=False):
return self.config_class(root_path, self.default_config)
#self.config_class = Config
#第3步:
class Config(dict):
发现app.config是一个dict类/派生类的对象,那么app.config 就可以app.config['xx'] = 'xxx' 设置值,内部是实现了__setitem__方法
方式二:app.config.from_pyfile('settings.py') 源码分析: class Config(dict): def from_pyfile(self, filename, silent=False): #找到文件 filename = os.path.join(self.root_path, filename) #创建了一个模块,里面没有东西 d = types.ModuleType('config') d.__file__ = filename try: #打开文件,获取所有内容 #再将配置文件里的所有值封装到上一步创建的模块中 with open(filename, mode='rb') as config_file: exec(compile(config_file.read(), filename, 'exec'), d.__dict__) #执行from_object方法 self.from_object(d) return True def from_object(self, obj): #获取创建的模块中的所有值,如果是大写,给app.config设置值 for key in dir(obj): if key.isupper(): self[key] = getattr(obj, key)
方式三:
os.environ['FLAKS-SETTINGS'] = 'settings.py' app.config.from_envvar('FLAKS-SETTINGS')
源码分析:
class Config(dict):
def from_envvar(self, variable_name, silent=False):
#获取settings文件
rv = os.environ.get(variable_name)
#发现还是执行了from_pyfile方法
return self.from_pyfile(rv, silent=silent)
方式四:
app.config.from_object('settings.DevConfig')
源码分析:
class Config(dict):
def from_object(self, obj):
#4.1如果settings.DevConfig 是字符串类/派生类的对象
if isinstance(obj, string_types):
#4.2
obj = import_string(obj)
#4.3步 获取类中的所有值,并给app.config设置值
for key in dir(obj):
if key.isupper():
self[key] = getattr(obj, key)
#4.2步:
def import_string(import_name, silent=False):
#把settings.DevConfig按照.右切1次,得到模块名和类名
module_name, obj_name = import_name.rsplit('.', 1)
try:
module = __import__(module_name, None, None, [obj_name])
#获取模块中的类并返回
try:
return getattr(module, obj_name)