Python脚本如何初始化项目配置

wen python案例 27

本文目录导读:

Python脚本如何初始化项目配置

  1. 使用配置文件(推荐)
  2. 使用环境变量
  3. 使用argparse命令行参数
  4. 综合使用(推荐的最佳实践)
  5. 使用配置管理库(推荐)
  6. 推荐的选择

我会详细说明Python脚本初始化项目配置的几种常用方法。

使用配置文件(推荐)

JSON配置文件

import json
import os
class ProjectConfig:
    def __init__(self, config_file='config.json'):
        self.config_file = config_file
        self.config = self.load_config()
        self.setup_project()
    def load_config(self):
        """加载配置文件"""
        if os.path.exists(self.config_file):
            with open(self.config_file, 'r', encoding='utf-8') as f:
                return json.load(f)
        else:
            return self.create_default_config()
    def create_default_config(self):
        """创建默认配置"""
        default_config = {
            "project": {
                "name": "my_project",
                "version": "1.0.0",
                "author": "developer"
            },
            "database": {
                "host": "localhost",
                "port": 5432,
                "database": "mydb",
                "user": "admin",
                "password": ""
            },
            "paths": {
                "log_dir": "./logs",
                "data_dir": "./data",
                "output_dir": "./output"
            },
            "logging": {
                "level": "INFO",
                "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
            }
        }
        # 保存默认配置
        with open(self.config_file, 'w', encoding='utf-8') as f:
            json.dump(default_config, f, indent=4, ensure_ascii=False)
        print(f"已创建默认配置文件: {self.config_file}")
        return default_config
    def setup_project(self):
        """初始化项目目录结构"""
        for path in self.config.get('paths', {}).values():
            os.makedirs(path, exist_ok=True)
            print(f"创建目录: {path}")
    def get(self, key, default=None):
        """获取配置项"""
        keys = key.split('.')
        value = self.config
        for k in keys:
            if isinstance(value, dict):
                value = value.get(k, default)
            else:
                return default
        return value
# 使用示例
if __name__ == "__main__":
    config = ProjectConfig()
    print(f"项目名称: {config.get('project.name')}")
    print(f"数据库主机: {config.get('database.host')}")

YAML配置文件

import yaml
import os
class YAMLProjectConfig:
    def __init__(self, config_file='config.yaml'):
        self.config_file = config_file
        self.config = self.load_config()
        self.setup_project()
    def load_config(self):
        """加载YAML配置文件"""
        if os.path.exists(self.config_file):
            with open(self.config_file, 'r', encoding='utf-8') as f:
                return yaml.safe_load(f)
        else:
            return self.create_default_config()
    def create_default_config(self):
        """创建默认YAML配置"""
        default_config = {
            'project': {
                'name': 'my_project',
                'version': '1.0.0',
                'author': 'developer'
            },
            'database': {
                'host': 'localhost',
                'port': 5432,
                'database': 'mydb',
                'user': 'admin',
                'password': '${DB_PASSWORD}'  # 环境变量引用
            },
            'paths': {
                'log_dir': './logs',
                'data_dir': './data',
                'output_dir': './output'
            },
            'logging': {
                'level': 'INFO',
                'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
            }
        }
        with open(self.config_file, 'w', encoding='utf-8') as f:
            yaml.dump(default_config, f, default_flow_style=False, allow_unicode=True)
        print(f"已创建默认配置文件: {self.config_file}")
        return default_config
    def resolve_env_vars(self, value):
        """解析环境变量"""
        if isinstance(value, str) and value.startswith('${') and value.endswith('}'):
            env_var = value[2:-1]
            return os.getenv(env_var, value)
        return value
    def setup_project(self):
        """初始化项目目录"""
        for path in self.config.get('paths', {}).values():
            os.makedirs(path, exist_ok=True)
    def get(self, key, default=None):
        """获取配置项(支持环境变量解析)"""
        keys = key.split('.')
        value = self.config
        for k in keys:
            if isinstance(value, dict):
                value = value.get(k, default)
            else:
                return default
        return self.resolve_env_vars(value)
# 安装PyYAML: pip install pyyaml
if __name__ == "__main__":
    config = YAMLProjectConfig()
    print(f"项目名称: {config.get('project.name')}")

使用环境变量

import os
from dotenv import load_dotenv
class EnvConfig:
    def __init__(self, env_file='.env'):
        self.env_file = env_file
        self.load_env()
        self.setup_project()
    def load_env(self):
        """加载环境变量文件"""
        if os.path.exists(self.env_file):
            load_dotenv(self.env_file)
            print(f"已加载环境变量文件: {self.env_file}")
        else:
            self.create_default_env()
    def create_default_env(self):
        """创建默认环境变量文件"""
        default_env = """
# 项目配置
PROJECT_NAME=my_project
PROJECT_VERSION=1.0.0
# 数据库配置
DB_HOST=localhost
DB_PORT=5432
DB_NAME=mydb
DB_USER=admin
DB_PASSWORD=
# 路径配置
LOG_DIR=./logs
DATA_DIR=./data
OUTPUT_DIR=./output
# 日志配置
LOG_LEVEL=INFO
"""
        with open(self.env_file, 'w') as f:
            f.write(default_env.strip())
        load_dotenv(self.env_file)
        print(f"已创建默认环境变量文件: {self.env_file}")
    def setup_project(self):
        """创建项目目录"""
        dirs = [
            os.getenv('LOG_DIR', './logs'),
            os.getenv('DATA_DIR', './data'),
            os.getenv('OUTPUT_DIR', './output')
        ]
        for dir_path in dirs:
            os.makedirs(dir_path, exist_ok=True)
            print(f"创建目录: {dir_path}")
    def get(self, key, default=None):
        """获取环境变量"""
        return os.getenv(key, default)
# 安装python-dotenv: pip install python-dotenv
if __name__ == "__main__":
    config = EnvConfig()
    print(f"项目名称: {config.get('PROJECT_NAME')}")
    print(f"数据库主机: {config.get('DB_HOST')}")

使用argparse命令行参数

import argparse
import os
import json
class ArgparseConfig:
    def __init__(self):
        self.parser = argparse.ArgumentParser(description='项目初始化配置')
        self.add_arguments()
        self.args = self.parse_args()
        self.setup_project()
    def add_arguments(self):
        """添加命令行参数"""
        self.parser.add_argument('--config', type=str, 
                               help='配置文件路径')
        self.parser.add_argument('--project-name', type=str, 
                               default='my_project', help='项目名称')
        self.parser.add_argument('--db-host', type=str, 
                               default='localhost', help='数据库主机')
        self.parser.add_argument('--db-port', type=int, 
                               default=5432, help='数据库端口')
        self.parser.add_argument('--log-level', type=str, 
                               default='INFO', choices=['DEBUG', 'INFO', 'WARNING', 'ERROR'])
        self.parser.add_argument('--init-dirs', action='store_true', 
                               help='是否初始化目录')
    def parse_args(self):
        """解析参数"""
        args = self.parser.parse_args()
        # 如果指定了配置文件,从配置文件加载
        if args.config and os.path.exists(args.config):
            with open(args.config, 'r') as f:
                config_data = json.load(f)
                # 合并配置
                for key, value in config_data.items():
                    if not getattr(args, key.replace('-', '_'), None):
                        setattr(args, key.replace('-', '_'), value)
        return args
    def setup_project(self):
        """初始化项目"""
        if self.args.init_dirs:
            dirs = ['./logs', './data', './output']
            for dir_path in dirs:
                os.makedirs(dir_path, exist_ok=True)
                print(f"创建目录: {dir_path}")
    def get(self, key, default=None):
        """获取配置值"""
        return getattr(self.args, key.replace('-', '_'), default)
# 使用示例
if __name__ == "__main__":
    config = ArgparseConfig()
    print(f"项目名称: {config.get('project_name')}")
    print(f"数据库主机: {config.get('db_host')}")

综合使用(推荐的最佳实践)

import os
import json
import argparse
from pathlib import Path
from dotenv import load_dotenv
class ProjectInitializer:
    """项目初始化器 - 综合多种配置方式"""
    def __init__(self):
        self.config = {
            'project': {},
            'database': {},
            'paths': {},
            'logging': {}
        }
        self.initialize()
    def initialize(self):
        """按优先级加载配置"""
        # 1. 加载默认配置文件
        self.load_default_config()
        # 2. 加载环境变量
        self.load_env_config()
        # 3. 加载命令行参数
        self.load_cli_config()
        # 4. 设置项目
        self.setup_project()
    def load_default_config(self):
        """加载默认配置"""
        config_file = 'config.json'
        if os.path.exists(config_file):
            with open(config_file, 'r') as f:
                self.config.update(json.load(f))
                print(f"已加载配置文件: {config_file}")
        else:
            self.create_default_config()
    def create_default_config(self):
        """创建默认配置"""
        default_config = {
            'project': {
                'name': 'my_project',
                'version': '1.0.0',
                'debug': False
            },
            'database': {
                'host': 'localhost',
                'port': 5432,
                'name': 'mydb'
            },
            'paths': {
                'log_dir': './logs',
                'data_dir': './data',
                'temp_dir': './temp'
            },
            'logging': {
                'level': 'INFO',
                'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
            }
        }
        with open('config.json', 'w') as f:
            json.dump(default_config, f, indent=4)
        print("已创建默认配置文件: config.json")
        self.config.update(default_config)
    def load_env_config(self):
        """加载环境变量配置"""
        if os.path.exists('.env'):
            load_dotenv('.env')
        # 环境变量覆盖配置
        env_mapping = {
            'PROJECT_NAME': ('project', 'name'),
            'DB_HOST': ('database', 'host'),
            'DB_PORT': ('database', 'port'),
            'LOG_LEVEL': ('logging', 'level')
        }
        for env_key, config_path in env_mapping.items():
            env_value = os.getenv(env_key)
            if env_value:
                section, key = config_path
                if section in self.config:
                    if key == 'port':
                        self.config[section][key] = int(env_value)
                    else:
                        self.config[section][key] = env_value
    def load_cli_config(self):
        """加载命令行参数"""
        parser = argparse.ArgumentParser(description='项目初始化')
        parser.add_argument('--project-name', type=str, help='项目名称')
        parser.add_argument('--db-host', type=str, help='数据库主机')
        parser.add_argument('--db-port', type=int, help='数据库端口')
        parser.add_argument('--debug', action='store_true', help='调试模式')
        parser.add_argument('--init', action='store_true', help='初始化项目')
        args, unknown = parser.parse_known_args()
        if args.project_name:
            self.config['project']['name'] = args.project_name
        if args.db_host:
            self.config['database']['host'] = args.db_host
        if args.db_port:
            self.config['database']['port'] = args.db_port
        if args.debug:
            self.config['project']['debug'] = True
    def setup_project(self):
        """初始化项目目录结构"""
        paths = self.config.get('paths', {})
        for name, path in paths.items():
            Path(path).mkdir(parents=True, exist_ok=True)
            print(f"创建目录: {path}")
    def get(self, section, key, default=None):
        """获取配置值"""
        try:
            return self.config[section][key]
        except KeyError:
            return default
    def __str__(self):
        return json.dumps(self.config, indent=2, ensure_ascii=False)
# 使用示例
if __name__ == "__main__":
    initializer = ProjectInitializer()
    print("\n当前配置:")
    print(initializer)
    # 使用配置
    print(f"\n项目名称: {initializer.get('project', 'name')}")
    print(f"数据库主机: {initializer.get('database', 'host')}")
    print(f"日志级别: {initializer.get('logging', 'level')}")

使用配置管理库(推荐)

# 使用 dynaconf 库
# pip install dynaconf
from dynaconf import Dynaconf
settings = Dynaconf(
    envvar_prefix="MYPROJECT",
    settings_files=['settings.toml', '.secrets.toml'],
    environments=True,
    load_dotenv=True,
)
# settings.toml
"""
[default]
project_name = "my_project"
version = "1.0.0"
debug = false
[development]
debug = true
database_host = "localhost"
[production]
database_host = "prod-server.com"
"""

推荐的选择

  1. 小型项目:使用 jsonyaml 配置文件
  2. 需要安全配置:使用环境变量 + .env 文件
  3. 命令行工具:使用 argparse
  4. 大型项目:使用 dynaconfpython-decouple 等配置管理库
  5. 最佳实践:组合使用 JSON/YAML 配置 + 环境变量 + 命令行参数

这些方法可以根据项目需求灵活选择和组合使用。

抱歉,评论功能暂时关闭!