前言
常見(jiàn)的應(yīng)用配置方式有環(huán)境變量和配置文件,對(duì)于微服務(wù)應(yīng)用,還會(huì)從配置中心加載配置,比如nacos、etcd等,有的應(yīng)用還會(huì)把部分配置寫(xiě)在數(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類(lèi)型為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è)字典類(lèi)型,通過(guò)key就可以訪問(wèn)到
<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)問(wè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í)行輸出,無(wú)論使用tomllib
或toml
,返回的都是dict類(lèi)型,都可以直接使用key訪問(wèn)。
<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")
綜合示例
一般來(lái)說(shuō)配置解析相關(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
示例:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-777068.html
from pkg.config import TomlParser
config = TomlParser("conf/app.toml")
print(config.load())
執(zhí)行輸出文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-777068.html
{'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'}}
到了這里,關(guān)于[python]常用配置讀取方法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!