詳解python中常用配置的讀取方法
前言
常見的應(yīng)用配置方式有環(huán)境變量和配置文件,對(duì)于微服務(wù)應(yīng)用,還會(huì)從配置中心加載配置,比如nacos、etcd等,有的應(yīng)用還會(huì)把部分配置寫在數(shù)據(jù)庫(kù)中。此處主要記錄從環(huán)境變量、.env
文件、.ini
文件、.yaml
文件、.toml
文件、.json
文件讀取配置。
ini文件
ini
文件格式一般如下:
[mysql] type = "mysql" host = "127.0.0.1" port = 3306 username = "root" password = "123456" dbname = "test" [redis] host = "127.0.0.1" port = 6379 password = "123456" db = "5"
使用python標(biāo)準(zhǔn)庫(kù)中的configparser
可以讀取ini文件。
import configparser import os def read_ini(filename: str = "conf/app.ini"): """ Read configuration from ini file. :param filename: filename of the ini file """ config = configparser.ConfigParser() if not os.path.exists(filename): raise FileNotFoundError(f"File {filename} not found") config.read(filename, encoding="utf-8") return config
config類型為configparser.ConfigParser
,可以使用如下方式讀取
config = read_ini("conf/app.ini") for section in config.sections(): for k,v in config.items(section): print(f"{section}.{k}: {v}")
讀取輸出示例
mysql.type: "mysql"
mysql.host: "127.0.0.1"
mysql.port: 3306
mysql.username: "root"
mysql.password: "123456"
mysql.dbname: "test"
redis.host: "127.0.0.1"
redis.port: 6379
redis.password: "123456"
redis.db: "5"
yaml文件
yaml文件內(nèi)容示例如下:
database: mysql: host: "127.0.0.1" port: 3306 user: "root" password: "123456" dbname: "test" redis: host: - "192.168.0.10" - "192.168.0.11" port: 6379 password: "123456" db: "5" log: directory: "logs" level: "debug" maxsize: 100 maxage: 30 maxbackups: 30 compress: true
讀取yaml文件需要安裝pyyaml
pip install pyyaml
讀取yaml文件的示例代碼
import yaml import os def read_yaml(filename: str = "conf/app.yaml"): if not os.path.exists(filename): raise FileNotFoundError(f"File {filename} not found") with open(filename, "r", encoding="utf-8") as f: config = yaml.safe_load(f.read()) return config if __name__ == "__main__": config = read_yaml("conf/app.yaml") print(type(config)) print(config)
執(zhí)行輸出,可以看到config
是個(gè)字典類型,通過key就可以訪問到
<class 'dict'>
{'database': {'mysql': {'host': '127.0.0.1', 'port': 3306, 'user': 'root', 'password': '123456', 'dbname': 'test'}, 'redis': {'host': ['192.168.0.10', '192.168.0.11'], 'port': 6379, 'password': '123456', 'db': '5'}}, 'log': {'directory': 'logs', 'level': 'debug', 'maxsize': 100, 'maxage': 30, 'maxbackups': 30, 'compress': True}}
toml文件
toml文件比較像yaml,但是不要求縮進(jìn)格式。如果比較討厭yaml的縮進(jìn)問題,那么可以考慮下使用toml。一個(gè)簡(jiǎn)單的toml文件示例如下:
[database] dbtype = "mysql" [database.mysql] host = "127.0.0.1" port = 3306 user = "root" password = "123456" dbname = "test" [database.redis] host = ["192.168.0.10", "192.168.0.11"] port = 6379 password = "123456" db = "5" [log] directory = "logs" level = "debug"
如果python版本高于3.11,其標(biāo)準(zhǔn)庫(kù)tomllib
就可以讀取toml文件。讀取toml文件的第三方庫(kù)也有很多,個(gè)人一般使用toml
pip install toml
讀取toml文件的示例代碼
import tomllib # python version >= 3.11 import toml import os def read_toml_1(filename: str = "conf/app.toml"): """ Read configuration from toml file using tomllib that is python standard package. Python version >= 3.11 """ if not os.path.exists(filename): raise FileNotFoundError(f"File {filename} not found") with open(filename, "rb") as f: config = tomllib.load(f) return config def read_toml_2(filename: str = "conf/app.toml"): """ Read configuration from toml file using toml package. """ if not os.path.exists(filename): raise FileNotFoundError(f"File {filename} not found") with open(filename, "r" ,encoding="utf-8") as f: config = toml.load(f) return config if __name__ == "__main__": config = read_toml_1("conf/app.yaml") # config = read_toml_2("conf/app.yaml") print(type(config)) print(config)
執(zhí)行輸出,無論使用tomllib
或toml
,返回的都是dict類型,都可以直接使用key訪問。
<class 'dict'>
{'database': {'mysql': {'host': '127.0.0.1', 'port': 3306, 'user': 'root', 'password': '123456', 'dbname': 'test'}, 'redis': {'host': ['192.168.0.10', '192.168.0.11'], 'port': 6379, 'password': '123456', 'db': '5'}}, 'log': {'directory': 'logs', 'level': 'debug', 'maxsize': 100, 'maxage': 30, 'maxbackups': 30, 'compress': True}}
json文件
使用標(biāo)準(zhǔn)庫(kù)json
即可讀取json文件,json配置文件示例:
{ "database": { "mysql": { "host": "127.0.0.1", "port": 3306, "user": "root", "password": "123456", "dbname": "test" }, "redis": { "host": [ "192.168.0.10", "192.168.0.11" ], "port": 6379, "password": "123456", "db": "5" } }, "log": { "level": "debug", "dir": "logs" } }
解析的示例代碼如下
import json import os def read_json(filename: str = "conf/app.json") -> dict: """ Read configuration from json file using json package. """ if not os.path.exists(filename): raise FileNotFoundError(f"File {filename} not found") with open(filename, "r", encoding="utf-8") as f: config = json.load(f) return config if __name__ == "__main__": config = read_json("conf/app.yaml") print(type(config)) print(config)
執(zhí)行輸出
<class 'dict'>
{'database': {'mysql': {'host': '127.0.0.1', 'port': 3306, 'user': 'root', 'password': '123456', 'dbname': 'test'}, 'redis': {'host': ['192.168.0.10', '192.168.0.11'], 'port': 6379, 'password': '123456', 'db': '5'}}, 'log': {'level': 'debug', 'dir': 'logs'}}
.env文件
從.env
文件讀取鍵值對(duì)配置,并將它們添加到環(huán)境變量中,添加后可以使用os.getenv()
獲取。
讀取.env
文件需要安裝第三方庫(kù)
pip install python-dotenv
.env
文件示例
MYSQL_HOST="127.0.0.1" MYSQL_PORT=3306 MYSQL_USERNAME="root" MYSQL_PASSWORD="123456" MYSQL_DATABASE="test"
示例代碼
import os import dotenv def read_dotenv(filename: str = "conf/.env"): if not os.path.exists(filename): raise FileNotFoundError(f"File {filename} not found") load_dotenv(dotenv_path=filename, encoding="utf-8", override=True) config = dict(os.environ) return config if __name__ == "__main__": config = read_json("conf/app.yaml") for k,v in config.items(): if k.startswith("MYSQL_"): print(f"{k}: {v}")
讀取環(huán)境變量
在標(biāo)準(zhǔn)庫(kù)os
中有以下常用的和環(huán)境變量相關(guān)的方法,具體可參考官方文檔:https://docs.python.org/zh-cn/3/library/os.html
os.environ
,一個(gè)mapping對(duì)象,其中鍵值是代表進(jìn)程環(huán)境的字符串。例如 environ["HOME"]
# example import os config = dict(os.environ) for k,v in config.items(): print(k,v)
os.getenv(key, default=None)
。如果環(huán)境變量 key 存在則將其值作為字符串返回,如果不存在則返回 default。
os.putenv(key, value)
。設(shè)置環(huán)境變量,官方文檔推薦直接修改os.environ
。例如:os.putenv("MYSQL_HOST", "127.0.0.1")
os.unsetenv(key)
。刪除名為 key 的環(huán)境變量,官方文檔推薦直接修改os.environ
。例如:os.unsetenv("MYSQL_HOST")
綜合示例
一般來說配置解析相關(guān)代碼會(huì)放到單獨(dú)的包中,配置文件也會(huì)放到單獨(dú)的目錄,這里給個(gè)簡(jiǎn)單的示例。
目錄結(jié)構(gòu)如下,conf
目錄存放配置文件,pkg/config.py
用于解析配置,main.py
為程序入口。
.
├── conf
│ ├── app.ini
│ ├── app.json
│ ├── app.toml
│ └── app.yaml
├── main.py
└── pkg
├── config.py
└── __init__.py
pkg/__init__.py
文件為空,pkg/config.py
內(nèi)容如下:
import configparser import os import yaml import tomllib import json import abc from dotenv import load_dotenv class Configer(metaclass=abc.ABCMeta): def __init__(self, filename: str): self.filename = filename @abc.abstractmethod def load(self): raise NotImplementedError(f"subclass must implement this method") def file_exists(self): if not os.path.exists(self.filename): raise FileNotFoundError(f"File {self.filename} not found") class IniParser(Configer): def __init__(self, filename: str): super().__init__(filename) def load(self): super().file_exists() config = configparser.ConfigParser() config.read(self.filename, encoding="utf-8") return config class YamlParser(Configer): def __init__(self, filename: str): super().__init__(filename) def load(self): super().file_exists() with open(self.filename, "r", encoding="utf-8") as f: config = yaml.safe_load(f.read()) return config class TomlParser(Configer): def __init__(self, filename: str): super().__init__(filename) def load(self): super().file_exists() with open(self.filename, "rb") as f: config = tomllib.load(f) return config class JsonParser(Configer): def __init__(self, cfgtype: str, filename: str = None): super().__init__(cfgtype, filename) def load(self): super().file_exists() with open(self.filename, "r", encoding="utf-8") as f: config = json.load(f) return config class DotenvParser(Configer): def __init__(self, filename: str = None): super().__init__(filename) def load(self): super().file_exists() load_dotenv(self.filename, override=True) config = dict(os.environ) return config
main.py
示例:
from pkg.config import TomlParser config = TomlParser("conf/app.toml") print(config.load())
執(zhí)行輸出
{'database': {'dbtype': 'mysql', 'mysql': {'host': '127.0.0.1', 'port': 3306, 'user': 'root', 'password': '123456', 'dbname': 'test'}, 'redis': {'host': ['192.168.0.10', '192.168.0.11'], 'port': 6379, 'password': '123456', 'db': '5'}}, 'log': {'directory': 'logs', 'level': 'debug'}}
以上就是詳解python中常用配置的讀取方法的詳細(xì)內(nèi)容,更多關(guān)于python配置讀取的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python之time模塊的時(shí)間戳,時(shí)間字符串格式化與轉(zhuǎn)換方法(13位時(shí)間戳)
今天小編就為大家分享一篇Python之time模塊的時(shí)間戳,時(shí)間字符串格式化與轉(zhuǎn)換方法(13位時(shí)間戳),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-08-08Python 中 function(#) (X)格式 和 (#)在Python3.*中的注意事項(xiàng)
這篇文章主要介紹了Python 中 function(#) (X)格式 和 (#)在Python3.*中的注意事項(xiàng),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-11-11Pyspark讀取parquet數(shù)據(jù)過程解析
這篇文章主要介紹了pyspark讀取parquet數(shù)據(jù)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03python進(jìn)程的狀態(tài)、創(chuàng)建及使用方法詳解
這篇文章主要介紹了python進(jìn)程的狀態(tài)、創(chuàng)建及使用方法,結(jié)合實(shí)例形式詳細(xì)分析了Python進(jìn)程的概念、原理、工作狀態(tài)、創(chuàng)建以及使用方法,需要的朋友可以參考下2019-12-12腳本測(cè)試postman快速導(dǎo)出python接口測(cè)試過程示例
這篇文章主要介紹了關(guān)于腳本測(cè)試postman快速導(dǎo)出python接口測(cè)試示例的過程操作,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-09-09深入了解和應(yīng)用Python 裝飾器 @decorator
在編程過程中,經(jīng)常遇到這樣的場(chǎng)景:登錄校驗(yàn),權(quán)限校驗(yàn),日志記錄等,這些功能代碼在各個(gè)環(huán)節(jié)都可能需要,但又十分雷同,通過裝飾器來抽象、剝離這部分代碼可以很好解決這類場(chǎng)景,這篇文章主要介紹了Python的裝飾器 @decorator,探討了使用的方式,需要的朋友可以參考下2019-04-04Python中ArcPy柵格裁剪柵格(批量對(duì)齊柵格圖像范圍并統(tǒng)一行數(shù)與列數(shù))
本文介紹基于Python中ArcPy模塊,實(shí)現(xiàn)基于柵格圖像批量裁剪柵格圖像,同時(shí)對(duì)齊各個(gè)柵格圖像的空間范圍,統(tǒng)一其各自行數(shù)與列數(shù)的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02