2025-11-12
Python
00

目录

🤔 Why Choose INI Configuration Files?
🛠️ Python Built-in Tool: configparser Module
📖 Reading INI Configuration Files
✍️ Writing and Modifying Configuration
💼 Practical Case: Windows Desktop App Configuration Management
🔧 Advanced Tips & Best Practices
🛡️ Security Considerations
🎨 Configuration File Template Feature
🔄 Configuration File Validation
📱 GUI Framework Integration Example
🎯 Key Takeaways

Python Complete Guide to INI Configuration File Handling: Make Your App Configuration Management More Elegant

In Python development on the Windows platform, we often need to deal with various configuration files. Whether it's a desktop application, automation script, or HMI program, proper configuration management is key to project success. Today we'll dive into the most classic configuration file format in Python — the INI file — and its read/write operations. This article starts from real development needs and, through rich code examples, helps you master all INI file handling techniques to easily handle various configuration management scenarios.

🤔 Why Choose INI Configuration Files?

Among many configuration file formats, INI files have unique advantages:

Clear structure: Use sections and key-value pairs; even non-technical users can easily understand it

Strong compatibility: Native support on Windows; many legacy applications use this format

Good readability: Plain text format, supports comments, easy to maintain and debug

A typical INI file structure:

Ini
; 这是注释 [database] host = localhost port = 3306 username = admin password = 123456 [logging] level = INFO file_path = ./logs/app.log max_size = 10MB

🛠️ Python Built-in Tool: configparser Module

The Python standard library provides the configparser module, the first-choice tool for handling INI files. Let's start from basic usage:

📖 Reading INI Configuration Files

Python
import configparser def read_config(): # Create ConfigParser object config = configparser.ConfigParser() # Read configuration file config.read('config.ini', encoding='utf-8') # Get all section names sections = config.sections() print(f"配置文件包含的节: {sections}") # Read all key-value pairs of a specific section db_config = dict(config['database']) print(f"数据库配置: {db_config}") # Read specific configuration items host = config.get('database', 'host') port = config.getint('database', 'port') # Automatically converted to int print(f"数据库地址: {host}:{port}") return config # Usage example if __name__ == "__main__": config = read_config()

image.png

✍️ Writing and Modifying Configuration

Python
import configparser def create_config(): config = configparser.ConfigParser() # Add database section config.add_section('database') config.set('database', 'host', 'localhost') config.set('database', 'port', '3306') config.set('database', 'username', 'admin') config.set('database', 'password', '123456') # Add logging section config.add_section('logging') config.set('logging', 'level', 'INFO') config.set('logging', 'file_path', './logs/app.log') config.set('logging', 'max_size', '10MB') # Write to file with open('config.ini', 'w', encoding='utf-8') as f: config.write(f) print("配置文件创建成功!") def update_config(): config = configparser.ConfigParser() config.read('config.ini', encoding='utf-8') # Modify existing configuration config.set('database', 'password', 'new_password') # Add new configuration items if not config.has_section('app'): config.add_section('app') config.set('app', 'version', '1.0.0') config.set('app', 'debug', 'False') # Save changes with open('config.ini', 'w', encoding='utf-8') as f: config.write(f) print("配置更新完成!") create_config() update_config()

image.png

💼 Practical Case: Windows Desktop App Configuration Management

Let's demonstrate best practices with a complete configuration management class:

Python
import configparser import os from pathlib import Path class ConfigManager: def __init__(self, config_file='app_config.ini'): self.config_file = config_file self.config = configparser.ConfigParser() # Ensure the config file exists if not os.path.exists(config_file): self._create_default_config() else: self.load_config() def _create_default_config(self): """Create default config file""" # App basic configuration self.config.add_section('app') self.config.set('app', 'title', 'Python桌面应用') self.config.set('app', 'version', '1.0.0') self.config.set('app', 'window_width', '1024') self.config.set('app', 'window_height', '768') self.config.set('app', 'auto_save', 'True') # Database configuration self.config.add_section('database') self.config.set('database', 'driver', 'sqlite') self.config.set('database', 'path', './data/app.db') self.config.set('database', 'backup_interval', '24') # User preferences self.config.add_section('preferences') self.config.set('preferences', 'theme', 'light') self.config.set('preferences', 'language', 'zh-CN') self.config.set('preferences', 'font_size', '12') self.save_config() print("已创建默认配置文件") def load_config(self): """Load config file""" try: self.config.read(self.config_file, encoding='utf-8') print("配置文件加载成功") except Exception as e: print(f"配置文件加载失败: {e}") self._create_default_config() def save_config(self): """Save config to file""" try: with open(self.config_file, 'w', encoding='utf-8') as f: self.config.write(f) print("配置保存成功") except Exception as e: print(f"配置保存失败: {e}") def get_app_config(self): """Get application config""" return { 'title': self.config.get('app', 'title'), 'version': self.config.get('app', 'version'), 'window_size': ( self.config.getint('app', 'window_width'), self.config.getint('app', 'window_height') ), 'auto_save': self.config.getboolean('app', 'auto_save') } def get_database_config(self): """Get database config""" return { 'driver': self.config.get('database', 'driver'), 'path': self.config.get('database', 'path'), 'backup_interval': self.config.getint('database', 'backup_interval') } def update_preference(self, key, value): """Update user preference""" self.config.set('preferences', key, str(value)) self.save_config() def get_preference(self, key, default=None): """Get user preference""" try: return self.config.get('preferences', key) except (configparser.NoSectionError, configparser.NoOptionError): return default def backup_config(self, backup_path=None): """Backup config file""" if backup_path is None: backup_path = f"{self.config_file}.backup" try: import shutil shutil.copy2(self.config_file, backup_path) print(f"配置文件已备份到: {backup_path}") return True except Exception as e: print(f"配置备份失败: {e}") return False # Usage example def demo_config_manager(): # Create config manager instance config_mgr = ConfigManager() # Get config info app_config = config_mgr.get_app_config() print(f"应用配置: {app_config}") db_config = config_mgr.get_database_config() print(f"数据库配置: {db_config}") # Update user preferences config_mgr.update_preference('theme', 'dark') config_mgr.update_preference('font_size', '14') # Get preference settings theme = config_mgr.get_preference('theme') font_size = config_mgr.get_preference('font_size') print(f"当前主题: {theme}, 字体大小: {font_size}") # Backup config config_mgr.backup_config() if __name__ == "__main__": demo_config_manager()

image.png

🔧 Advanced Tips & Best Practices

🛡️ Security Considerations

For sensitive information (like passwords), it's not recommended to store them directly in INI files. You can combine simple encoding:

Python
import base64 import configparser import os class SecureConfigManager: def __init__(self, config_file='secure_config.ini'): self.config_file = config_file self.config = configparser.ConfigParser() self.load_config() def encode_password(self, password): """Simple password encoding (for demo only; use stronger methods in real projects)""" return base64.b64encode(password.encode()).decode() def decode_password(self, encoded_password): """Decode password""" return base64.b64decode(encoded_password.encode()).decode() def set_secure_value(self, section, key, value): """Set a value that needs encoding""" if not self.config.has_section(section): self.config.add_section(section) encoded_value = self.encode_password(value) self.config.set(section, key, encoded_value) self.save_config() def get_secure_value(self, section, key): """Get decoded value""" try: encoded_value = self.config.get(section, key) return self.decode_password(encoded_value) except Exception as e: print(f"获取安全值失败: {e}") return None def load_config(self): if os.path.exists(self.config_file): self.config.read(self.config_file, encoding='utf-8') def save_config(self): with open(self.config_file, 'w', encoding='utf-8') as f: self.config.write(f) # Usage example secure_config = SecureConfigManager() secure_config.set_secure_value('database', 'password', 'my_secret_password') print(f"已保存密码: {secure_config.get_secure_value('database', 'password')}") password = secure_config.get_secure_value('database', 'password') print(f"解码后的密码: {password}")

image.png

🎨 Configuration File Template Feature

Python
def create_config_template(): """Create a configuration file template for users to customize""" template = """ ; =========================================== ; 应用程序配置文件模板 ; =========================================== [app] ; 应用程序基本信息 title = 我的Python应用 version = 1.0.0 window_width = 1024 window_height = 768 auto_save = True [database] ; 数据库连接配置 driver = sqlite path = ./data/app.db backup_interval = 24 [preferences] ; 用户偏好设置 theme = light language = zh-CN font_size = 12 [logging] ; 日志配置 level = INFO file_path = ./logs/app.log max_file_size = 10MB backup_count = 5 """ with open('config_template.ini', 'w', encoding='utf-8') as f: f.write(template) print("配置模板已创建,请根据需要修改后重命名为config.ini")

image.png

image.png

🔄 Configuration File Validation

Python
def validate_config(config_file='config.ini'): """Validate the integrity of the configuration file""" required_sections = ['app', 'database', 'preferences'] required_keys = { 'app': ['title', 'version', 'window_width', 'window_height'], 'database': ['driver', 'path'], 'preferences': ['theme', 'language'] } config = configparser.ConfigParser() try: config.read(config_file, encoding='utf-8') # Check required sections missing_sections = [] for section in required_sections: if not config.has_section(section): missing_sections.append(section) if missing_sections: print(f"缺少必需的配置节: {missing_sections}") return False # Check required keys missing_keys = {} for section, keys in required_keys.items(): section_missing = [] for key in keys: if not config.has_option(section, key): section_missing.append(key) if section_missing: missing_keys[section] = section_missing if missing_keys: print(f"缺少必需的配置项: {missing_keys}") return False print("配置文件验证通过!") return True except Exception as e: print(f"配置文件验证失败: {e}") return False

image.png

image.png

image.png

📱 GUI Framework Integration Example

In real Windows desktop app development, configuration management is usually tightly integrated with GUI frameworks:

Python
import os import tkinter as tk from tkinter import ttk, messagebox import configparser class SettingsWindow: def __init__(self, parent, config_manager): self.parent = parent self.config_mgr = config_manager self.window = tk.Toplevel(parent) self.window.title("应用设置") self.window.geometry("400x300") self.create_widgets() self.load_settings() def create_widgets(self): # Create notebook for grouped settings notebook = ttk.Notebook(self.window) # App settings page app_frame = ttk.Frame(notebook) notebook.add(app_frame, text="应用设置") # Window size settings ttk.Label(app_frame, text="窗口宽度:").grid(row=0, column=0, sticky='w', padx=5, pady=5) self.width_var = tk.StringVar() ttk.Entry(app_frame, textvariable=self.width_var).grid(row=0, column=1, padx=5, pady=5) ttk.Label(app_frame, text="窗口高度:").grid(row=1, column=0, sticky='w', padx=5, pady=5) self.height_var = tk.StringVar() ttk.Entry(app_frame, textvariable=self.height_var).grid(row=1, column=1, padx=5, pady=5) # Auto save setting self.auto_save_var = tk.BooleanVar() ttk.Checkbutton(app_frame, text="启用自动保存", variable=self.auto_save_var).grid(row=2, column=0, columnspan=2, sticky='w', padx=5, pady=5) # Preferences page pref_frame = ttk.Frame(notebook) notebook.add(pref_frame, text="偏好设置") # Theme setting ttk.Label(pref_frame, text="主题:").grid(row=0, column=0, sticky='w', padx=5, pady=5) self.theme_var = tk.StringVar() theme_combo = ttk.Combobox(pref_frame, textvariable=self.theme_var, values=['light', 'dark'], state='readonly') theme_combo.grid(row=0, column=1, padx=5, pady=5) # Font size setting ttk.Label(pref_frame, text="字体大小:").grid(row=1, column=0, sticky='w', padx=5, pady=5) self.font_size_var = tk.StringVar() font_combo = ttk.Combobox(pref_frame, textvariable=self.font_size_var, values=['10', '12', '14', '16', '18'], state='readonly') font_combo.grid(row=1, column=1, padx=5, pady=5) notebook.pack(fill='both', expand=True, padx=10, pady=10) # Button frame button_frame = ttk.Frame(self.window) button_frame.pack(fill='x', padx=10, pady=5) ttk.Button(button_frame, text="保存", command=self.save_settings).pack(side='right', padx=5) ttk.Button(button_frame, text="取消", command=self.window.destroy).pack(side='right', padx=5) ttk.Button(button_frame, text="恢复默认", command=self.reset_defaults).pack(side='left') def load_settings(self): """Load settings from config file""" app_config = self.config_mgr.get_app_config() self.width_var.set(str(app_config['window_size'][0])) self.height_var.set(str(app_config['window_size'][1])) self.auto_save_var.set(app_config['auto_save']) self.theme_var.set(self.config_mgr.get_preference('theme', 'light')) self.font_size_var.set(self.config_mgr.get_preference('font_size', '12')) def save_settings(self): """Save settings to config file""" try: # Save app settings self.config_mgr.config.set('app', 'window_width', self.width_var.get()) self.config_mgr.config.set('app', 'window_height', self.height_var.get()) self.config_mgr.config.set('app', 'auto_save', str(self.auto_save_var.get())) # Save preferences self.config_mgr.update_preference('theme', self.theme_var.get()) self.config_mgr.update_preference('font_size', self.font_size_var.get()) self.config_mgr.save_config() messagebox.showinfo("成功", "设置已保存!") self.window.destroy() except Exception as e: messagebox.showerror("错误", f"保存设置失败: {e}") def reset_defaults(self): """Reset to default settings""" self.width_var.set('1024') self.height_var.set('768') self.auto_save_var.set(True) self.theme_var.set('light') self.font_size_var.set('12') class ConfigManager: def __init__(self, config_path='app_settings.ini'): self.config_path = config_path self.config = configparser.ConfigParser() self.load_config() def load_config(self): if not os.path.exists(self.config_path): # Initialize default config self.config['app'] = { 'window_width': '1024', 'window_height': '768', 'auto_save': 'True' } self.config['preference'] = { 'theme': 'light', 'font_size': '12' } self.save_config() else: self.config.read(self.config_path, encoding='utf-8') def save_config(self): with open(self.config_path, 'w', encoding='utf-8') as configfile: self.config.write(configfile) def get_app_config(self): app_cfg = self.config['app'] width = int(app_cfg.get('window_width', '1024')) height = int(app_cfg.get('window_height', '768')) auto_save = app_cfg.get('auto_save', 'True') == 'True' return {'window_size': (width, height), 'auto_save': auto_save} def get_preference(self, key, default=None): return self.config['preference'].get(key, default) def update_preference(self, key, value): self.config['preference'][key] = value if __name__ == '__main__': root = tk.Tk() root.withdraw() config_mgr = ConfigManager() # Instantiate config manager s = SettingsWindow(root, config_mgr) s.window.mainloop()

image.png

🎯 Key Takeaways

Through this in-depth tutorial, we have mastered the core skills for handling INI configuration files in Python:

🔑 Core skill mastery: From basic configparser usage to advanced features, including various methods to read, write, and modify config files, enabling you to handle configuration management needs of varying complexity.

💼 Practical experience: The complete ConfigManager class and GUI integration examples demonstrate real-project best practices, including security considerations, configuration validation, template creation, and other advanced features.

🚀 Improved development efficiency: With these techniques, your Python apps will have more professional configuration management capabilities, improving user experience and code maintainability.

Although INI configuration files look simple, they are an indispensable skill in Python development on the Windows platform. Whether it's desktop apps, automation tools, or HMI programs, good configuration management makes your projects more professional and user-friendly. I hope this article helps you advance further on your Python development journey!

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!