Python讀寫JSON配置文件的簡(jiǎn)明學(xué)習(xí)指南
1. 基本讀寫操作
讀取 JSON 配置文件
import json
# 創(chuàng)建示例配置文件
config_data = {
"database": {
"host": "localhost",
"port": 3306,
"username": "admin"
},
"settings": {
"debug": True,
"log_level": "INFO"
}
}
with open("config.json", "w", encoding="utf-8") as f:
json.dump(config_data, f, indent=2, ensure_ascii=False)
# 讀取 JSON 文件
with open("config.json", "r", encoding="utf-8") as f:
config = json.load(f)
print("配置文件內(nèi)容:")
print(json.dumps(config, indent=2, ensure_ascii=False))
# 訪問配置值
db_host = config["database"]["host"]
debug_mode = config["settings"]["debug"]
print(f"\n數(shù)據(jù)庫(kù)主機(jī): {db_host}")
print(f"調(diào)試模式: {debug_mode}")
寫入 JSON 配置文件
import json
# 創(chuàng)建配置數(shù)據(jù)
config = {
"app": {
"name": "我的應(yīng)用",
"version": "1.0.0"
},
"server": {
"host": "0.0.0.0",
"port": 8080
}
}
# 寫入到文件
with open("app_config.json", "w", encoding="utf-8") as f:
json.dump(config, f, indent=4, ensure_ascii=False)
print("配置文件已保存到: app_config.json")
# 驗(yàn)證寫入
with open("app_config.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
print(f"應(yīng)用名稱: {loaded['app']['name']}")
print(f"服務(wù)器端口: {loaded['server']['port']}")
2. 簡(jiǎn)單配置管理器
import json
import os
from typing import Any, Dict
class SimpleConfig:
def __init__(self, filename: str = "config.json"):
self.filename = filename
self.config = {}
def load(self) -> Dict[str, Any]:
"""加載配置文件"""
if os.path.exists(self.filename):
with open(self.filename, "r", encoding="utf-8") as f:
self.config = json.load(f)
else:
self.config = self.get_default_config()
self.save()
return self.config
def save(self) -> None:
"""保存配置文件"""
with open(self.filename, "w", encoding="utf-8") as f:
json.dump(self.config, f, indent=2, ensure_ascii=False)
def get_default_config(self) -> Dict[str, Any]:
"""獲取默認(rèn)配置"""
return {
"app": {
"name": "默認(rèn)應(yīng)用",
"version": "1.0.0"
},
"database": {
"host": "localhost",
"port": 5432
}
}
def get(self, *keys) -> Any:
"""獲取配置值"""
value = self.config
for key in keys:
if isinstance(value, dict) and key in value:
value = value[key]
else:
return None
return value
def set(self, *keys_and_value) -> None:
"""設(shè)置配置值
參數(shù)格式: key1, key2, ..., value
例如: set("database", "host", "192.168.1.100")
"""
if len(keys_and_value) < 2:
raise ValueError("至少需要2個(gè)參數(shù): keys和value")
*keys, value = keys_and_value
# 遍歷到倒數(shù)第二個(gè)鍵
current = self.config
for key in keys[:-1]:
if key not in current or not isinstance(current[key], dict):
current[key] = {}
current = current[key]
# 設(shè)置最后一個(gè)鍵的值
current[keys[-1]] = value
self.save()
# 使用示例
config = SimpleConfig("my_config.json")
# 加載配置
config.load()
# 獲取配置
app_name = config.get("app", "name")
print(f"應(yīng)用名稱: {app_name}")
# 設(shè)置新配置
config.set("database", "host", "192.168.1.100")
config.set("app", "debug", True)
config.set("logging", "level", "DEBUG")
# 驗(yàn)證設(shè)置
print(f"數(shù)據(jù)庫(kù)主機(jī): {config.get('database', 'host')}")
print(f"調(diào)試模式: {config.get('app', 'debug')}")
print(f"日志級(jí)別: {config.get('logging', 'level')}")
# 查看完整的配置
print(f"\n完整配置: {json.dumps(config.config, indent=2, ensure_ascii=False)}")
# 清理臨時(shí)文件
if os.path.exists("my_config.json"):
os.remove("my_config.json")
3. 帶環(huán)境變量支持的配置
import json
import os
from typing import Any, Dict
class EnvConfig:
def __init__(self, config_file: str = "config.json", env_prefix: str = "APP_"):
self.config_file = config_file
self.env_prefix = env_prefix
self.config = {}
def load(self) -> Dict[str, Any]:
"""加載配置,環(huán)境變量?jī)?yōu)先于文件配置"""
# 1. 加載文件配置
if os.path.exists(self.config_file):
with open(self.config_file, "r", encoding="utf-8") as f:
self.config = json.load(f)
else:
self.config = {}
# 2. 用環(huán)境變量覆蓋
self._apply_env_vars()
return self.config
def _apply_env_vars(self) -> None:
"""應(yīng)用環(huán)境變量到配置"""
for env_key, env_value in os.environ.items():
if env_key.startswith(self.env_prefix):
# 轉(zhuǎn)換環(huán)境變量名: APP_DATABASE_HOST -> database.host
config_key = env_key[len(self.env_prefix):].lower()
# 轉(zhuǎn)換值類型
value = self._convert_value(env_value)
# 設(shè)置到配置中
self._set_nested(config_key, value)
def _convert_value(self, value: str) -> Any:
"""轉(zhuǎn)換字符串值為適當(dāng)類型"""
# 布爾值
if value.lower() in ("true", "false"):
return value.lower() == "true"
# 數(shù)字
try:
if "." in value:
return float(value)
return int(value)
except ValueError:
pass
# 列表(逗號(hào)分隔)
if "," in value:
return [item.strip() for item in value.split(",")]
return value
def _set_nested(self, key_path: str, value: Any) -> None:
"""設(shè)置嵌套配置"""
parts = key_path.split("_")
current = self.config
for part in parts[:-1]:
if part not in current or not isinstance(current[part], dict):
current[part] = {}
current = current[part]
current[parts[-1]] = value
def save(self) -> None:
"""保存配置到文件"""
with open(self.config_file, "w", encoding="utf-8") as f:
json.dump(self.config, f, indent=2, ensure_ascii=False)
# 使用示例
# 設(shè)置環(huán)境變量
os.environ["APP_DATABASE_HOST"] = "prod-db.example.com"
os.environ["APP_DEBUG"] = "true"
os.environ["APP_LOG_LEVEL"] = "WARNING"
# 創(chuàng)建文件配置
file_config = {
"database": {
"host": "localhost", # 將被環(huán)境變量覆蓋
"port": 3306
},
"app": {
"debug": False, # 將被環(huán)境變量覆蓋
"log_level": "INFO" # 將被環(huán)境變量覆蓋
}
}
# 保存文件配置
with open("env_config.json", "w", encoding="utf-8") as f:
json.dump(file_config, f, indent=2, ensure_ascii=False)
# 加載配置
config = EnvConfig("env_config.json")
config_data = config.load()
print("最終配置:")
print(json.dumps(config_data, indent=2, ensure_ascii=False))
# 清理
os.remove("env_config.json")
del os.environ["APP_DATABASE_HOST"]
del os.environ["APP_DEBUG"]
del os.environ["APP_LOG_LEVEL"]
4. 處理特殊數(shù)據(jù)類型的配置
import json
from datetime import datetime, date
from decimal import Decimal
from enum import Enum
from typing import Any
class CustomJSONEncoder(json.JSONEncoder):
"""自定義 JSON 編碼器,支持更多數(shù)據(jù)類型"""
def default(self, obj: Any) -> Any:
if isinstance(obj, (datetime, date)):
return obj.isoformat()
elif isinstance(obj, Decimal):
return float(obj)
elif isinstance(obj, Enum):
return obj.value
elif hasattr(obj, '__dict__'):
return obj.__dict__
return super().default(obj)
# 定義數(shù)據(jù)類型
class LogLevel(Enum):
DEBUG = "DEBUG"
INFO = "INFO"
WARNING = "WARNING"
ERROR = "ERROR"
# 創(chuàng)建包含特殊類型的數(shù)據(jù)
config_data = {
"app": {
"name": "數(shù)據(jù)分析",
"created": datetime.now(),
"version": "2.0.0"
},
"database": {
"host": "localhost",
"port": 5432,
"timeout": 30.5
},
"logging": {
"level": LogLevel.INFO,
"retention_days": Decimal("90.5")
},
"features": ["auth", "api", "dashboard"]
}
# 使用自定義編碼器保存
with open("special_config.json", "w", encoding="utf-8") as f:
json.dump(config_data, f, cls=CustomJSONEncoder, indent=2, ensure_ascii=False)
print("包含特殊類型的配置文件已保存")
# 讀取和驗(yàn)證
with open("special_config.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
print("\n讀取的配置:")
print(f"應(yīng)用名稱: {loaded['app']['name']}")
print(f"創(chuàng)建時(shí)間: {loaded['app']['created']}")
print(f"日志級(jí)別: {loaded['logging']['level']}")
print(f"保留天數(shù): {loaded['logging']['retention_days']}")
# 清理
import os
os.remove("special_config.json")
5. 配置驗(yàn)證
import json
from typing import Any, Dict, List
class ConfigValidator:
"""簡(jiǎn)單的配置驗(yàn)證器"""
def validate(self, config: Dict[str, Any], rules: Dict[str, Any]) -> List[str]:
"""驗(yàn)證配置"""
errors = []
for key, rule in rules.items():
if key not in config:
if rule.get("required", False):
errors.append(f"缺少必要字段: {key}")
continue
value = config[key]
value_type = rule.get("type")
# 檢查類型
if value_type and not isinstance(value, value_type):
errors.append(f"{key} 應(yīng)為 {value_type.__name__} 類型")
# 檢查枚舉值
if "enum" in rule and value not in rule["enum"]:
errors.append(f"{key} 的值 {value} 不在允許范圍內(nèi): {rule['enum']}")
# 檢查范圍
if "min" in rule and value < rule["min"]:
errors.append(f"{key} 的值 {value} 小于最小值 {rule['min']}")
if "max" in rule and value > rule["max"]:
errors.append(f"{key} 的值 {value} 大于最大值 {rule['max']}")
return errors
# 使用示例
config = {
"app": {
"name": "我的應(yīng)用",
"version": "1.0.0"
},
"database": {
"host": "localhost",
"port": 3306,
"timeout": 30
},
"server": {
"port": 8080,
"workers": 4
}
}
# 定義驗(yàn)證規(guī)則
validation_rules = {
"app": {
"type": dict,
"required": True
},
"database": {
"type": dict,
"required": True
},
"server": {
"type": dict,
"required": True
}
}
database_rules = {
"host": {
"type": str,
"required": True
},
"port": {
"type": int,
"required": True,
"min": 1,
"max": 65535
},
"timeout": {
"type": int,
"required": True,
"min": 1
}
}
# 驗(yàn)證配置
validator = ConfigValidator()
# 驗(yàn)證頂層
errors = validator.validate(config, validation_rules)
if errors:
print("配置驗(yàn)證失敗:")
for error in errors:
print(f" - {error}")
else:
print("? 頂層配置驗(yàn)證通過")
# 驗(yàn)證數(shù)據(jù)庫(kù)配置
db_errors = validator.validate(config["database"], database_rules)
if db_errors:
print("數(shù)據(jù)庫(kù)配置驗(yàn)證失敗:")
for error in db_errors:
print(f" - {error}")
else:
print("? 數(shù)據(jù)庫(kù)配置驗(yàn)證通過")
# 保存驗(yàn)證通過的配置
if not errors and not db_errors:
with open("validated_config.json", "w", encoding="utf-8") as f:
json.dump(config, f, indent=2, ensure_ascii=False)
print("\n? 配置已保存到: validated_config.json")
# 清理
import os
os.remove("validated_config.json")
快速使用總結(jié)
- 基本讀寫:使用
json.load()和json.dump() - 中文支持:添加
ensure_ascii=False - 格式美觀:使用
indent參數(shù) - 錯(cuò)誤處理:檢查文件是否存在
- 類型轉(zhuǎn)換:JSON 支持基本類型,復(fù)雜類型需要自定義處理
到此這篇關(guān)于Python讀寫JSON配置文件的簡(jiǎn)明學(xué)習(xí)指南的文章就介紹到這了,更多相關(guān)Python讀寫JSON配置文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python本地搭建靜態(tài)Web服務(wù)器的實(shí)現(xiàn)
本文主要介紹了Python本地搭建靜態(tài)Web服務(wù)器的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
Python數(shù)據(jù)可視化:冪律分布實(shí)例詳解
今天小編就為大家分享一篇Python數(shù)據(jù)可視化:冪律分布實(shí)例詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-12-12
Python實(shí)現(xiàn)讀寫sqlite3數(shù)據(jù)庫(kù)并將統(tǒng)計(jì)數(shù)據(jù)寫入Excel的方法示例
這篇文章主要介紹了Python實(shí)現(xiàn)讀寫sqlite3數(shù)據(jù)庫(kù)并將統(tǒng)計(jì)數(shù)據(jù)寫入Excel的方法,涉及Python針對(duì)sqlite3數(shù)據(jù)庫(kù)的讀取及Excel文件相關(guān)操作技巧,需要的朋友可以參考下2017-08-08
使用GitHub和Python實(shí)現(xiàn)持續(xù)部署的方法
這篇文章主要介紹了使用GitHub和Python實(shí)現(xiàn)持續(xù)部署的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-05-05
重寫django的model下的objects模型管理器方式
這篇文章主要介紹了重寫django的model下的objects模型管理器方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-05-05
python開發(fā)實(shí)時(shí)可視化儀表盤的示例
這篇文章主要介紹了python開發(fā)實(shí)時(shí)可視化儀表盤的示例,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下2021-05-05
django ajax發(fā)送post請(qǐng)求的兩種方法
這篇文章主要介紹了django ajax發(fā)送post請(qǐng)求的兩種方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01

