原始碼解析Flask的配置檔案

2022-05-26 13:06:16 字數 4319 閱讀 7238

在flask裡,我們常在主檔案中定義某些配置,比如:

實際上,flask中預設可以進行可選的配置項有很多。

如果在開發的過程中,把所有需要的配置項都定義在主檔案中,就會造成整個程式的目錄結構不合理,

如果需要重寫的flask配置項很多的時候,就可以把配置項用別的方式進行定義,然後匯入使用

flask的配置檔案是乙個flask.config.config物件

匯入config物件,可以發現config物件繼承字典,

config預設的配置有:

default_config = immutabledict()
通過檢視config物件的原始碼,可以知道flask的配置可以有以下幾種方式

匯入配置項的方式:

from_envvar方法的原始碼:

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

rv = os.environ.get(variable_name)

if not rv:

if silent:

return false

raise runtimeerror('the environment variable %r is not set '

'and as such configuration could not be '

'loaded. set this variable and make it '

'point to a configuration file' %

variable_name)

return self.from_pyfile(rv, silent=silent)

可以看到,從環境變數中匯入配置項的方法,就是從環境變數中找到並讀取對應的py檔名稱,然後內部呼叫from_pyfile方法處理讀取到的內容得到配置

從python檔案中獲取配置項的方式:

例如,建立乙個名為setting.py的檔案

setting.py檔案的內容為:

debug=true
from_pyfile方法的原始碼:

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__)

except ioerror as e:

if silent and e.errno in (errno.enoent, errno.eisdir):

return false

e.strerror = 'unable to load configuration file (%s)' % e.strerror

raise

self.from_object(d)

return true

從py檔案中匯入配置項的過程中,讀取引數中的python檔案的內容,進行編譯後exec方法執行,就得到所需要的配置項

需要注意的是:

python檔案可以是絕對路徑或者相對路徑,如果是相對路徑,則py檔案必須放在root_path目錄下,

from_object方法的原始碼:

def from_object(self, obj):

if isinstance(obj, string_types):

obj = import_string(obj)

for key in dir(obj):

if key.isupper():

self[key] = getattr(obj, key)

從物件中匯入配置項的過程中,首先判斷所傳入的物件名是否是字串,然後呼叫import_string方法處理字串形式的物件名

import_string方法的原始碼:

def import_string(import_name, silent=false):

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)

try:

module = __import__(module_name, none, none, [obj_name])

except importerror:

module = import_string(module_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])

可以看到,import_string方法,實際上是對字串形式的物件名執行rsplit方法,得到模組名和物件名

在模組可以被正常匯入之前,不停執行import_string方法,最後執行getattr方法從模組中獲取物件名

from_json方法的原始碼:

def from_json(self, filename, silent=false):

filename = os.path.join(self.root_path, filename)

try:

with open(filename) as json_file:

obj = json.loads(json_file.read())

except ioerror as e:

if silent and e.errno in (errno.enoent, errno.eisdir):

return false

e.strerror = 'unable to load configuration file (%s)' % e.strerror

raise

從json檔案中獲取配置項,實際上就是對json檔案執行json.loads方法,得到物件

else:

raise typeerror(

)if key.isupper():

self[key] = value

return true

把引數字典中的所有鍵值對新增到列表串,迴圈遍歷列表,讀取列表中每個元素的鍵和值

如果鍵為大寫,則key為配置選項,value為配置選項的值

get_namespace原始碼:

def get_namespace(self, namespace, lowercase=true, trim_namespace=true):

rv = {}

for k, v in iteritems(self):

if not k.startswith(namespace):

continue

if trim_namespace:

key = k[len(namespace):]

else:

key = k

if lowercase:

key = key.lower()

rv[key] = v

return rv

get_namespace方法,是從指定的命名空間或字首中進行匹配,返回包含配置項的子集的字典

迭代當前物件,獲取key和v,把key轉換為小寫格式,然後把key和v包含在乙個字典中

flask 配置檔案的原始碼分析

原始碼分析 第1步 class flask packageboundobject self.config self.make config instance relative config 第2步 def make config self,instance relative false return...

flask原始碼分析 配置檔案 四

class flask packageboundobject config class config 配置由誰來載入配置 default config immutabledict flask定義了一些預設配置,如果自己不配則使用default def init self 這個物件可像操作字典一樣去操...

spring原始碼分析(二)配置檔案的解析

最開始的入口,只是包了下resource public int loadbeandefinitions resource resource throws beandefinitionstoreexception1 儲存當前正在載入的資源 2 檢測是否有重複載入資源的情況 3 真正幹活的地方doloa...