原始碼解析Flask的配置檔案
在flask裡,我們常在主檔案中定義某些配置,比如:
app.debug = True
app.secret_key = `helloworld!!`
實際上,flask中預設可以進行可選的配置項有很多。
如果在開發的過程中,把所有需要的配置項都定義在主檔案中,就會造成整個程式的目錄結構不合理,
如果需要重寫的flask配置項很多的時候,就可以把配置項用別的方式進行定義,然後匯入使用
flask的配置檔案是一個flask.config.Config
物件
匯入Config物件,可以發現Config物件繼承字典,
Config預設的配置有:
default_config = ImmutableDict({
`DEBUG`: get_debug_flag(default=False),
`TESTING`: False,
`PROPAGATE_EXCEPTIONS`: None,
`PRESERVE_CONTEXT_ON_EXCEPTION`: None,
`SECRET_KEY`: None,
`PERMANENT_SESSION_LIFETIME`: timedelta(days=31),
`USE_X_SENDFILE`: False,
`LOGGER_NAME`: None,
`LOGGER_HANDLER_POLICY`: `always`,
`SERVER_NAME`: None,
`APPLICATION_ROOT`: None,
`SESSION_COOKIE_NAME`: `session`,
`SESSION_COOKIE_DOMAIN`: None,
`SESSION_COOKIE_PATH`: None,
`SESSION_COOKIE_HTTPONLY`: True,
`SESSION_COOKIE_SECURE`: False,
`SESSION_REFRESH_EACH_REQUEST`: True,
`MAX_CONTENT_LENGTH`: None,
`SEND_FILE_MAX_AGE_DEFAULT`: timedelta(hours=12),
`TRAP_BAD_REQUEST_ERRORS`: False,
`TRAP_HTTP_EXCEPTIONS`: False,
`EXPLAIN_TEMPLATE_LOADING`: False,
`PREFERRED_URL_SCHEME`: `http`,
`JSON_AS_ASCII`: True,
`JSON_SORT_KEYS`: True,
`JSONIFY_PRETTYPRINT_REGULAR`: True,
`JSONIFY_MIMETYPE`: `application/json`,
`TEMPLATES_AUTO_RELOAD`: None,
})
通過檢視Config物件的原始碼,可以知道flask的配置可以有以下幾種方式
1.在主檔案中定義(通常使用的方式)
app.debug = True
app.secret_key = `helloworld!!`
由於Config物件繼承了dict的方法和屬性,所以還可以使用app.config.update(配置項)的方式匯入配置項
2.從環境變數中匯入配置項
匯入配置項的方式:
app.config.from_envvar("環境變數名稱")
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
方法處理讀取到的內容得到配置
3.從python檔案中匯入
從python檔案中獲取配置項的方式:
app.config.from_pyfile("python檔名稱")
例如,建立一個名為setting.py的檔案
setting.py檔案的內容為:
DEBUG=True
然後使用app.config.from_pyfile("setting.py")
的方式匯入配置項
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目錄下,
4.從物件中匯入配置項
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方法從模組中獲取物件名
5.from_json:從json字串中獲取配置項
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
return self.from_mapping(obj)
從json檔案中獲取配置項,實際上就是對json檔案執行json.loads方法,得到物件
然後內部呼叫from_mapping
方法處理所得到的物件
6.from_mapping:從dict字典中獲取配置項
from_mapping方法的原始碼:
def from_mapping(self, *mapping, **kwargs):
mappings = []
if len(mapping) == 1:
if hasattr(mapping[0], `items`):
mappings.append(mapping[0].items())
else:
mappings.append(mapping[0])
elif len(mapping) > 1:
raise TypeError(
`expected at most 1 positional argument, got %d` % len(mapping)
)
mappings.append(kwargs.items())
for mapping in mappings:
for (key, value) in mapping:
if key.isupper():
self[key] = value
return True
把引數字典中的所有鍵值對新增到列表串,迴圈遍歷列表,讀取列表中每個元素的鍵和值
如果鍵為大寫,則key為配置選項,value為配置選項的值
7.get_namespace:從名稱空間中獲取配置選項
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包含在一個字典中
相關文章
- .Net Core中的配置檔案原始碼解析原始碼
- flask 原始碼解析Flask原始碼
- flask 原始碼解析:sessionFlask原始碼Session
- flask 原始碼解析:路由Flask原始碼路由
- SpringBoot原始碼解析-配置檔案的載入Spring Boot原始碼
- flask 原始碼解析:簡介Flask原始碼
- flask 原始碼解析:請求Flask原始碼
- flask 原始碼解析:響應Flask原始碼
- mybatis原始碼配置檔案解析之五:解析mappers標籤(解析XML對映檔案)MyBatis原始碼APPXML
- flask-login 原始碼解析Flask原始碼
- flask 原始碼解析:上下文Flask原始碼
- Laravel Config—— 配置檔案的載入與原始碼解析Laravel原始碼
- Lucene原始碼解析--Lock檔案原始碼
- 學習Hibernate原始碼三_Hibernate中的配置檔案解析原始碼
- mybatis原始碼配置檔案解析之五:解析mappers標籤流程圖MyBatis原始碼APP流程圖
- flask 原始碼解析:應用啟動流程Flask原始碼
- ZooKeeper原始碼解析(5)-Snapshot檔案的格式原始碼
- 增加程式碼的通用性-解析配置檔案
- 從原始碼看Flask框架配置管理原始碼Flask框架
- Nginx配置檔案解析Nginx
- redis配置檔案解析Redis
- Hibernate的配置檔案解析
- Lucene原始碼解析--刪除文件檔案(.del)原始碼
- Android程式碼混淆配置(Proguard檔案解析)Android
- 深入Mybatis原始碼——配置解析MyBatis原始碼
- Benchmarksql的props配置檔案解析SQL
- java解析yaml配置檔案JavaYAML
- DHCP常用配置檔案解析
- Nginx配置檔案示例解析Nginx
- Lucene原始碼解析--Compound File 組合檔案原始碼
- Springboot 載入配置檔案原始碼分析Spring Boot原始碼
- 【Spring原始碼分析】配置檔案讀取流程Spring原始碼
- Mendmix程式碼解析:百搭的配置檔案讀取工具ResourceUtils
- Ubuntu 22.04 + Pycharm + Flask 配置 Flask 專案UbuntuPyCharmFlask
- 文盤Rust -- 配置檔案解析Rust
- Flask快速入門day 01(flask介紹、快速使用、配置檔案、路由系統)Flask路由
- Android 開源專案原始碼解析 -->PhotoView 原始碼解析(七)Android原始碼View
- Flask——檔案上傳Flask