Python读写JSON配置文件的简明学习指南

 更新时间:2026年01月04日 08:29:52   作者:老歌老听老掉牙  
这篇文章主要为大家详细介绍了Python读写JSON配置文件的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

1. 基本读写操作

读取 JSON 配置文件

import json

# 创建示例配置文件
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("配置文件内容:")
    print(json.dumps(config, indent=2, ensure_ascii=False))
    
# 访问配置值
db_host = config["database"]["host"]
debug_mode = config["settings"]["debug"]
print(f"\n数据库主机: {db_host}")
print(f"调试模式: {debug_mode}")

写入 JSON 配置文件

import json

# 创建配置数据
config = {
    "app": {
        "name": "我的应用",
        "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")

# 验证写入
with open("app_config.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)
    print(f"应用名称: {loaded['app']['name']}")
    print(f"服务器端口: {loaded['server']['port']}")

2. 简单配置管理器

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]:
        """获取默认配置"""
        return {
            "app": {
                "name": "默认应用",
                "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:
        """设置配置值
        参数格式: key1, key2, ..., value
        例如: set("database", "host", "192.168.1.100")
        """
        if len(keys_and_value) < 2:
            raise ValueError("至少需要2个参数: keys和value")
        
        *keys, value = keys_and_value
        
        # 遍历到倒数第二个键
        current = self.config
        for key in keys[:-1]:
            if key not in current or not isinstance(current[key], dict):
                current[key] = {}
            current = current[key]
        
        # 设置最后一个键的值
        current[keys[-1]] = value
        self.save()

# 使用示例
config = SimpleConfig("my_config.json")

# 加载配置
config.load()

# 获取配置
app_name = config.get("app", "name")
print(f"应用名称: {app_name}")

# 设置新配置
config.set("database", "host", "192.168.1.100")
config.set("app", "debug", True)
config.set("logging", "level", "DEBUG")

# 验证设置
print(f"数据库主机: {config.get('database', 'host')}")
print(f"调试模式: {config.get('app', 'debug')}")
print(f"日志级别: {config.get('logging', 'level')}")

# 查看完整的配置
print(f"\n完整配置: {json.dumps(config.config, indent=2, ensure_ascii=False)}")

# 清理临时文件
if os.path.exists("my_config.json"):
    os.remove("my_config.json")

3. 带环境变量支持的配置

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]:
        """加载配置,环境变量优先于文件配置"""
        # 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. 用环境变量覆盖
        self._apply_env_vars()
        
        return self.config
    
    def _apply_env_vars(self) -> None:
        """应用环境变量到配置"""
        for env_key, env_value in os.environ.items():
            if env_key.startswith(self.env_prefix):
                # 转换环境变量名: APP_DATABASE_HOST -> database.host
                config_key = env_key[len(self.env_prefix):].lower()
                
                # 转换值类型
                value = self._convert_value(env_value)
                
                # 设置到配置中
                self._set_nested(config_key, value)
    
    def _convert_value(self, value: str) -> Any:
        """转换字符串值为适当类型"""
        # 布尔值
        if value.lower() in ("true", "false"):
            return value.lower() == "true"
        
        # 数字
        try:
            if "." in value:
                return float(value)
            return int(value)
        except ValueError:
            pass
        
        # 列表(逗号分隔)
        if "," in value:
            return [item.strip() for item in value.split(",")]
        
        return value
    
    def _set_nested(self, key_path: str, value: Any) -> None:
        """设置嵌套配置"""
        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)

# 使用示例
# 设置环境变量
os.environ["APP_DATABASE_HOST"] = "prod-db.example.com"
os.environ["APP_DEBUG"] = "true"
os.environ["APP_LOG_LEVEL"] = "WARNING"

# 创建文件配置
file_config = {
    "database": {
        "host": "localhost",  # 将被环境变量覆盖
        "port": 3306
    },
    "app": {
        "debug": False,  # 将被环境变量覆盖
        "log_level": "INFO"  # 将被环境变量覆盖
    }
}

# 保存文件配置
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. 处理特殊数据类型的配置

import json
from datetime import datetime, date
from decimal import Decimal
from enum import Enum
from typing import Any

class CustomJSONEncoder(json.JSONEncoder):
    """自定义 JSON 编码器,支持更多数据类型"""
    
    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)

# 定义数据类型
class LogLevel(Enum):
    DEBUG = "DEBUG"
    INFO = "INFO"
    WARNING = "WARNING"
    ERROR = "ERROR"

# 创建包含特殊类型的数据
config_data = {
    "app": {
        "name": "数据分析",
        "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("包含特殊类型的配置文件已保存")

# 读取和验证
with open("special_config.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)
    print("\n读取的配置:")
    print(f"应用名称: {loaded['app']['name']}")
    print(f"创建时间: {loaded['app']['created']}")
    print(f"日志级别: {loaded['logging']['level']}")
    print(f"保留天数: {loaded['logging']['retention_days']}")

# 清理
import os
os.remove("special_config.json")

5. 配置验证

import json
from typing import Any, Dict, List

class ConfigValidator:
    """简单的配置验证器"""
    
    def validate(self, config: Dict[str, Any], rules: Dict[str, Any]) -> List[str]:
        """验证配置"""
        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} 应为 {value_type.__name__} 类型")
            
            # 检查枚举值
            if "enum" in rule and value not in rule["enum"]:
                errors.append(f"{key} 的值 {value} 不在允许范围内: {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": "我的应用",
        "version": "1.0.0"
    },
    "database": {
        "host": "localhost",
        "port": 3306,
        "timeout": 30
    },
    "server": {
        "port": 8080,
        "workers": 4
    }
}

# 定义验证规则
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
    }
}

# 验证配置
validator = ConfigValidator()

# 验证顶层
errors = validator.validate(config, validation_rules)
if errors:
    print("配置验证失败:")
    for error in errors:
        print(f"  - {error}")
else:
    print("✓ 顶层配置验证通过")

# 验证数据库配置
db_errors = validator.validate(config["database"], database_rules)
if db_errors:
    print("数据库配置验证失败:")
    for error in db_errors:
        print(f"  - {error}")
else:
    print("✓ 数据库配置验证通过")

# 保存验证通过的配置
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")

快速使用总结

  • 基本读写:使用 json.load()json.dump()
  • 中文支持:添加 ensure_ascii=False
  • 格式美观:使用 indent 参数
  • 错误处理:检查文件是否存在
  • 类型转换:JSON 支持基本类型,复杂类型需要自定义处理

到此这篇关于Python读写JSON配置文件的简明学习指南的文章就介绍到这了,更多相关Python读写JSON配置文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python的内建模块itertools的使用解析

    Python的内建模块itertools的使用解析

    这篇文章主要介绍了Python的内建模块itertools的使用解析,itertools是python的迭代器模块,itertools提供的工具相当高效且节省内存,Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数,需要的朋友可以参考下
    2023-09-09
  • Python虚拟环境的创建和使用详解

    Python虚拟环境的创建和使用详解

    这篇文章主要给大家介绍了关于Python虚拟环境的创建和使用的相关资料,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • sklearn线性逻辑回归和非线性逻辑回归的实现

    sklearn线性逻辑回归和非线性逻辑回归的实现

    这篇文章主要介绍了sklearn线性逻辑回归和非线性逻辑回归的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Python中shape计算矩阵的方法示例

    Python中shape计算矩阵的方法示例

    这篇文章主要介绍了Python中shape计算矩阵的方法,涉及Python数学运算相关实现技巧,需要的朋友可以参考下
    2017-04-04
  • Python元组解密不可变的数据之美探索

    Python元组解密不可变的数据之美探索

    这篇文章主要介绍了Python元组解密:不可变的数据之美,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • 关于pygame自定义窗口创建及相关操作指南

    关于pygame自定义窗口创建及相关操作指南

    对于开发一个游戏来说,窗口的显示肯定是前提中的前提,对于pygame来说,只需要一小段代码就可以初始化窗口,下面这篇文章主要给大家介绍了关于pygame自定义窗口创建及相关操作的相关资料,需要的朋友可以参考下
    2022-07-07
  • 关于Python中浮点数精度处理的技巧总结

    关于Python中浮点数精度处理的技巧总结

    双精度浮点数(double)是计算机使用的一种数据类型,使用 64 位(8字节) 来存储一个浮点数。下面这篇文章主要给大家总结介绍了关于Python中浮点数精度处理的技巧,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-08-08
  • Python字符和字符值(ASCII或Unicode码值)转换方法

    Python字符和字符值(ASCII或Unicode码值)转换方法

    这篇文章主要介绍了Python字符和字符值(ASCII或Unicode码值)转换方法,即把字符串在ASCII值或者Unicode值之间相与转换的方法,需要的朋友可以参考下
    2015-05-05
  • 详解Python如何利用Pandas与NumPy进行数据清洗

    详解Python如何利用Pandas与NumPy进行数据清洗

    许多数据科学家认为获取和清理数据的初始步骤占工作的 80%,花费大量时间来清理数据集并将它们归结为可以使用的形式。本文将利用 Python 的 Pandas和 NumPy 库来清理数据,需要的可以参考一下
    2022-04-04
  • Python Prometheus接口揭秘数据科学新技巧

    Python Prometheus接口揭秘数据科学新技巧

    本篇文章将分享Prometheus API的基本概念到PromQL查询语言的应用,再到如何通过Python与Prometheus API进行无缝交互,通过丰富的示例代码和详细的讲解,将解锁使用Python进行实时监控的奇妙世界,为读者打开更广阔的数据分析视野
    2024-01-01

最新评论