Python中如何优化可导出为CSV行的类属性维护?
优化方案
核心思路是用统一的映射字典管理外部标识与内部字段的对应关系,结合Python的动态属性操作,避免重复修改多处代码。
重构后的DataRow类
from typing import List, Dict, Optional class DataRow: # 1. 定义CSV表头对应的内部字段名 fields: List[str] = ['id', 'name', 'created', 'time'] # 2. 统一维护外部reference到内部字段的映射关系 reference_map: Dict[str, str] = { 'my id': 'id', 'item name': 'name', 'date': 'created', 'time': 'time' } def __init__(self) -> None: # 自动初始化所有字段为默认值,避免属性不存在报错 for field in self.fields: setattr(self, field, None) def get_labels(self) -> List[str]: return self.fields def set_item(self, reference: str, value: str) -> None: # 通过映射找到对应内部字段,动态赋值 field = self.reference_map.get(reference) if field: setattr(self, field, value) def get_item(self, key: str) -> Optional[str]: # 支持按内部字段名或外部reference取值 if key in self.fields: return getattr(self, key) field = self.reference_map.get(key) return getattr(self, field, None) if field else None
关键优化点
- 新增字段仅需两处修改:在
fields列表添加内部字段名,在reference_map补充外部标识与内部字段的对应关系,无需修改set_item/get_item方法,也不用逐个定义类属性。 - 动态属性操作:用
setattr和getattr代替硬编码的属性赋值/取值,彻底消除重复代码。 - 自动初始化:
__init__方法自动为所有字段设置默认值,避免访问不存在的属性抛出异常。
修正后的DataFile类
原add_row方法缺少实例参数self,同时类变量存储实例数据易引发问题,修正后如下:
from typing import List import csv class DataFile: name: str rows: List[DataRow] def __init__(self, name: str) -> None: self.name = name self.rows = [] # 用实例变量存储当前文件的行数据 def open(self): # 示例:读取CSV文件并生成DataRow实例 with open(self.name, 'r', newline='') as f: reader = csv.DictReader(f) for row_dict in reader: data_row = DataRow() for field in DataRow.fields: setattr(data_row, field, row_dict.get(field)) self.rows.append(data_row) def save(self): # 示例:将rows写入CSV文件 if not self.rows: return with open(self.name, 'w', newline='') as f: writer = csv.DictWriter(f, fieldnames=self.rows[0].get_labels()) writer.writeheader() for row in self.rows: writer.writerow({field: getattr(row, field) for field in DataRow.fields}) def add_row(self, row: DataRow) -> None: self.rows.append(row)
额外简化建议
如果fields不需要额外补充字段,可以直接从reference_map的取值生成,这样仅需维护reference_map一处:
reference_map: Dict[str, str] = { 'my id': 'id', 'item name': 'name', 'date': 'created', 'time': 'time' } fields: List[str] = list(reference_map.values())
内容的提问来源于stack exchange,提问作者Ewan
相关产品推荐
相关产品推荐

