本文来源公众号“python”,仅用于学术分享,侵权删,干货满满。
原文链接:Python开发进阶:构建可复用工具类的3种核心模式
在专业的Python开发过程中,代码复用是提高开发效率和代码质量的关键。通过创建自定义工具类,可以将常用功能封装起来,使其更易于维护和使用。
工具类设计原则
设计高质量的工具类需要遵循一些基本原则。工具类应当功能单一,职责明确,避免过度膨胀。接口设计应当简洁直观,降低使用门槛。良好的错误处理和文档说明是不可或缺的。这些原则帮助构建可靠且易于维护的工具类。
常见工具类封装模式
1、静态方法封装
静态方法非常适合封装无需维护状态的纯函数。以文件操作为例,创建一个文件工具类:
import os
import json
import csv
from typing import Dict, List, Any
class FileUtils:
@staticmethod
def read_json(file_path: str) -> Dict:
"""读取JSON文件并返回字典对象"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
return json.load(f)
except Exception as e:
print(f"读取JSON文件失败: {e}")
return {}
@staticmethod
def save_json(data: Dict, file_path: str, indent: int = 4) -> bool:
"""将字典数据保存为JSON文件"""
try:
os.makedirs(os.path.dirname(file_path), exist_ok=True)
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=indent)
returnTrue
except Exception as e:
print(f"保存JSON文件失败: {e}")
returnFalse
@staticmethod
def read_csv(file_path: str, has_header: bool = True) -> List[Dict]:
"""读取CSV文件并返回字典列表"""
try:
results = []
with open(file_path, 'r', encoding='utf-8') as f:
reader = csv.reader(f)
headers = next(reader) if has_header elseNone
ifnot has_header:
headers = [f"col_{i}"for i in range(len(next(reader)))]
f.seek(0) # 重置文件指针
for row in reader:
results.append({headers[i]: value for i, value in enumerate(row)})
return results
except Exception as e:
print(f"读取CSV文件失败: {e}")
return []
# 使用示例
config = FileUtils.read_json('config.json')
user_data = FileUtils.read_csv('users.csv')
静态方法的优点是使用简单,无需实例化,适合独立的功能函数封装。
2、上下文管理器封装
对于需要资源管理的操作,上下文管理器是很好的选择。以数据库连接为例:
import sqlite3
from typing import List, Dict, Any, Optional
class DatabaseManager:
def __init__(self, db_path: str):
self.db_path = db_path
self.conn = None
def __enter__(self):
self.conn = sqlite3.connect(self.db_path)
self.conn.row_factory = sqlite3.Row # 启用行工厂,返回类字典对象
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if self.conn:
self.conn.close()
def query(self, sql: str, params: tuple = ()) -> List[Dict]:
"""执行查询并返回结果"""
cursor = self.conn.cursor()
cursor.execute(sql, params)
results = [dict(row) for row in cursor.fetchall()]
cursor.close()
return results
def execute(self, sql: str, params: tuple = ()) -> int:
"""执行更新操作并返回影响的行数"""
cursor = self.conn.cursor()
cursor.execute(sql, params)
self.conn.commit()
affected = cursor.rowcount
cursor.close()
return affected
# 使用示例
with DatabaseManager('app.db') as db:
users = db.query("SELECT * FROM users WHERE age > ?", (18,))
db.execute("UPDATE users SET status = ? WHERE id = ?", ('active', 1))
上下文管理器确保资源正确释放,非常适合数据库连接、文件操作等场景。
3、配置管理工具类
应用程序通常需要处理配置,一个专用的配置管理类能显著简化这一工作:
import os
import json
from typing import Any, Dict, Optional
class ConfigManager:
_instance = None
def __new__(cls, config_path: str = None):
if cls._instance isNone:
cls._instance = super(ConfigManager, cls).__new__(cls)
cls._instance._initialized = False
return cls._instance
def __init__(self, config_path: str = None):
if self._initialized:
return
self.config_path = config_path or os.path.join(os.getcwd(), 'config.json')
self.config = {}
self.load()
self._initialized = True
def load(self) -> bool:
"""加载配置文件"""
try:
if os.path.exists(self.config_path):
with open(self.config_path, 'r', encoding='utf-8') as f:
self.config = json.load(f)
returnTrue
returnFalse
except Exception as e:
print(f"加载配置失败: {e}")
returnFalse
def save(self) -> bool:
"""保存配置到文件"""
try:
with open(self.config_path, 'w', encoding='utf-8') as f:
json.dump(self.config, f, ensure_ascii=False, indent=4)
returnTrue
except Exception as e:
print(f"保存配置失败: {e}")
returnFalse
def get(self, key: str, default: Any = None) -> Any:
"""获取配置项"""
keys = key.split('.')
value = self.config
for k in keys:
if isinstance(value, dict) and k in value:
value = value[k]
else:
return default
return value
def set(self, key: str, value: Any) -> None:
"""设置配置项"""
keys = key.split('.')
config = self.config
for i, k in enumerate(keys[:-1]):
if k notin config:
config[k] = {}
config = config[k]
config[keys[-1]] = value
# 使用示例
config = ConfigManager()
db_host = config.get('database.host', 'localhost')
config.set('app.debug', True)
config.save()
该工具类实现了单例模式,确保全局只有一个配置实例,并支持多级配置访问。
实用工具类示例
实现一个日志工具类,展示如何简化日志记录:
import logging
import os
from datetime import datetime
class LoggerUtil:
_loggers = {}
@staticmethod
def get_logger(name: str, level: int = logging.INFO, log_file: str = None):
"""获取或创建一个日志记录器"""
if name in LoggerUtil._loggers:
return LoggerUtil._loggers[name]
# 创建新的日志记录器
logger = logging.getLogger(name)
logger.setLevel(level)
# 控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(level)
console_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(console_format)
logger.addHandler(console_handler)
# 文件处理器(可选)
if log_file:
os.makedirs(os.path.dirname(log_file), exist_ok=True)
file_handler = logging.FileHandler(log_file, encoding='utf-8')
file_handler.setLevel(level)
file_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(file_format)
logger.addHandler(file_handler)
LoggerUtil._loggers[name] = logger
return logger
# 使用示例
logger = LoggerUtil.get_logger("app", log_file="logs/app.log")
logger.info("应用启动")
logger.error("发生错误", exc_info=True)
这个工具类提供了获取配置好的logger的便捷方法,同时维护缓存避免重复创建。
总结
自定义工具类封装是Python开发中提高效率的重要手段。通过合理设计工具类,可以显著减少重复代码,提高代码可读性和可维护性。在实际开发中,应根据具体需求选择适当的封装模式。静态方法适合无状态的纯函数;上下文管理器适合需要资源管理的操作;单例模式适合全局服务如配置管理。高质量的工具类应该有清晰的接口设计、完善的错误处理和详细的文档说明。通过不断积累和优化工具类库,团队可以建立起自己的代码资产,大幅提升开发效率。
THE END !
文章结束,感谢阅读。您的点赞,收藏,评论是我继续更新的动力。大家有推荐的公众号可以评论区留言,共同学习,一起进步。