在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...