枚举映射函数的最优实现:多文件类型路径生成方案探讨
最优文件类型-文件名映射实现方案
我有4种不同的文件类型,每种类型需根据索引映射到不同的文件名格式,请问最优实现方式是什么?
以下是我尝试的两种方案,但都存在问题:
方案一:枚举存储lambda函数
from pathlib import Path from enum import Enum base_path = "/a/b/c/d" class FileType(Enum): IMG = lambda index: f"img_{index}.nii.gz" IMG_SEGMENTATION = lambda index: f"img_{index}_segmentation.nii.gz" SUB_IMG = lambda index: f"img_sub_{index}.nii.gz" SUB_IMG_SEGMENTATION = lambda index: f"img_sub_{index}_segmentation.nii.gz" def get_path(file_type: FileType, index): path = Path(base_path) / file_type.value(index) if not path.exists(): raise FileNotFoundError return path
缺点:用枚举存储函数而非整数/字符串这类常规枚举值,违背了枚举的设计初衷。
方案二:新增中间映射函数
from pathlib import Path from enum import Enum, auto base_path = "/a/b/c/d" class FileType(Enum): IMG = auto() IMG_SEGMENTATION = auto() SUB_IMG = auto() SUB_IMG_SEGMENTATION = auto() def file_type_to_name(file_type: FileType, index: int) -> str: if file_type == FileType.IMG: return f"img_{index}.nii.gz" if file_type == FileType.IMG_SEGMENTATION: return f"img_{index}_segmentation.nii.gz" if file_type == FileType.SUB_IMG: return f"img_sub_{index}.nii.gz" if file_type == FileType.SUB_IMG_SEGMENTATION: return f"img_sub_{index}_segmentation.nii.gz" def get_path(file_type: FileType, index): path = Path(base_path) / file_type_to_name(file_type, index) if not path.exists(): raise FileNotFoundError return path
缺点:新增枚举文件类型时,必须同步修改file_type_to_name函数,不符合开闭原则,容易遗漏。
推荐最优实现:枚举成员携带格式字符串
我们可以让枚举成员存储对应的文件名格式模板,然后给枚举类添加一个生成文件名的方法,这样既遵循枚举的设计规范,又能做到新增类型时无需修改其他代码:
from pathlib import Path from enum import Enum base_path = "/a/b/c/d" class FileType(Enum): IMG = "img_{index}.nii.gz" IMG_SEGMENTATION = "img_{index}_segmentation.nii.gz" SUB_IMG = "img_sub_{index}.nii.gz" SUB_IMG_SEGMENTATION = "img_sub_{index}_segmentation.nii.gz" def get_filename(self, index: int) -> str: return self.value.format(index=index) def get_path(file_type: FileType, index: int) -> Path: path = Path(base_path) / file_type.get_filename(index) if not path.exists(): raise FileNotFoundError(f"文件不存在:{path}") return path
优势说明
- 符合枚举设计初衷:枚举成员存储的是字符串格式模板,属于常规枚举值类型
- 扩展性强:新增文件类型时,只需在
FileType枚举中添加新成员及其对应的格式字符串,无需修改其他函数 - 代码更简洁:把文件名生成逻辑封装在枚举类内部,职责单一,可读性更好
如果需要更灵活的格式生成逻辑(比如部分类型需要额外参数或预处理),也可以通过枚举的__init__方法初始化多属性:
from pathlib import Path from enum import Enum base_path = "/a/b/c/d" class FileType(Enum): # 格式:(模板字符串, 可选的索引预处理函数) IMG = ("img_{index}.nii.gz", lambda idx: idx) IMG_SEGMENTATION = ("img_{index}_segmentation.nii.gz", lambda idx: idx) SUB_IMG = ("img_sub_{index}.nii.gz", lambda idx: f"sub{idx}") # 示例预处理逻辑 SUB_IMG_SEGMENTATION = ("img_sub_{index}_segmentation.nii.gz", lambda idx: f"sub{idx}") def __init__(self, template: str, preprocess=lambda x: x): self.template = template self.preprocess = preprocess def get_filename(self, index: int) -> str: processed_idx = self.preprocess(index) return self.template.format(index=processed_idx) def get_path(file_type: FileType, index: int) -> Path: path = Path(base_path) / file_type.get_filename(index) if not path.exists(): raise FileNotFoundError(f"文件不存在:{path}") return path
这种方式兼顾了灵活性和枚举的规范性,适合复杂场景下的扩展。
内容的提问来源于stack exchange,提问作者Chessnut
相关产品推荐
相关产品推荐

