原始碼解析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包含在一個字典中
相關文章
- SpringBoot原始碼解析-配置檔案的載入Spring Boot原始碼
- .Net Core中的配置檔案原始碼解析原始碼
- mybatis原始碼配置檔案解析之五:解析mappers標籤(解析XML對映檔案)MyBatis原始碼APPXML
- flask-login 原始碼解析Flask原始碼
- mybatis原始碼配置檔案解析之五:解析mappers標籤流程圖MyBatis原始碼APP流程圖
- 增加程式碼的通用性-解析配置檔案
- Benchmarksql的props配置檔案解析SQL
- Springboot 載入配置檔案原始碼分析Spring Boot原始碼
- 從原始碼看Flask框架配置管理原始碼Flask框架
- DHCP常用配置檔案解析
- java解析yaml配置檔案JavaYAML
- 深入Mybatis原始碼——配置解析MyBatis原始碼
- Mendmix程式碼解析:百搭的配置檔案讀取工具ResourceUtils
- Ubuntu 22.04 + Pycharm + Flask 配置 Flask 專案UbuntuPyCharmFlask
- 文盤Rust -- 配置檔案解析Rust
- Flask快速入門day 01(flask介紹、快速使用、配置檔案、路由系統)Flask路由
- SpringBoot 如何解析配置檔案中的list?Spring Boot
- Flask——檔案上傳Flask
- 原始碼解析.Net中IConfiguration配置的實現原始碼
- nacos統一配置中心原始碼解析原始碼
- mybatis的全域性配置檔案SqlMapConfig.xml解析MyBatisSQLXML
- Spring框架裡解析配置檔案的準確位置Spring框架
- weex 原始碼解析(二) -- vue 檔案轉為js(Android視角)原始碼VueJSAndroid
- springMVC---配置檔案解析(web.xml)SpringMVCWebXML
- Vue原始碼探究-原始碼檔案組織Vue原始碼
- Flask 配置靜態資原始檔夾static_url_path、static_folderFlask
- SOFA-MOSN原始碼解析—配置詳解原始碼
- SpringBoot專案配置檔案中密碼的加密Spring Boot密碼加密
- nodejs的tream(流)解析與模擬檔案讀寫流原始碼實現NodeJS原始碼
- Fabric 1.0原始碼分析(28) Orderer #localconfig(Orderer配置檔案定義)原始碼
- Spring系列之手寫註解與配置檔案的解析Spring
- NPM酷庫047:ini,解析INI配置檔案NPM
- golang常用庫:配置檔案解析庫-viper使用Golang
- 萬字解析XML配置對映為BeanDefinition的原始碼XMLBean原始碼
- 檔案解析,在mysql配置和檢查項一樣的專案MySql
- 設定grub配置檔案中的螢幕解析度
- 專案中常用的 .env 檔案原理原始碼分析原始碼
- SpringBoot原始碼解析-Bean的載入與自動化配置Spring Boot原始碼Bean