Python如何迭代类属性?批量处理属性读取二进制文件避免重复编码?
实现方案
- 首先将所有字段的元数据(偏移位置、读取长度)统一存在类级别的配置字典中,不需要单独定义零散的
_xxx字符串属性,维护更方便,也支持遍历操作 - 利用Python的
__getattr__魔术方法动态处理属性读取逻辑,不需要为每个字段单独编写读取函数 - 将mmap读取逻辑封装到类内部,避免原代码中重复创建实例、重复打开文件的冗余操作,同时把属性缓存到实例中,避免重复读取文件
优化后代码
import mmap class Song: # 统一配置所有字段:属性名对应 (偏移量, 读取长度) _FIELD_META = { "title": (72, 42), "artist": (335, 68), "album_artist": (115, 4), "date": (412, 6), "frequency": (24, 4), "channel": (22, 2), "xrate": (28, 4), "int_tag": (20, 2) } def __init__(self, path): self.path = path # 缓存已读取的属性,避免重复读文件 self._cache = {} def __getattr__(self, name): # 仅处理我们预定义的字段 if name not in self._FIELD_META: raise AttributeError(f"'Song' object has no attribute '{name}'") # 已读取过的字段直接返回缓存值 if name in self._cache: return self._cache[name] # 读取对应字段的字节数据 offset, length = self._FIELD_META[name] with open(self.path, 'r+b') as f: with mmap.mmap(f.fileno(), 0) as mm: mm.seek(offset) raw_data = mm.read(length) # 可根据实际文件编码调整解码规则,这里用utf-8兼容常见场景,忽略非法字节 result = raw_data.decode('utf-8', errors='ignore').strip() self._cache[name] = result return result
使用示例
# 实例化时传入文件路径 song_obj = Song("你的音频文件路径") # 直接访问属性即可自动读取对应内容,无需调用额外的读取方法 print(song_obj.title) print(song_obj.artist) # 遍历所有字段的内容 for field_name in Song._FIELD_META: print(f"{field_name}: {getattr(song_obj, field_name)}")
扩展说明
如果后续需要新增字段,只需要在_FIELD_META字典中增加一行配置即可,不需要修改任何读取逻辑,也不用新增单独的读取函数。如果有部分字段需要特殊的解码/处理逻辑,可以在配置中增加第三个参数存储处理函数,在读取时调用即可。
内容的提问来源于stack exchange,提问作者CLipp
相关产品推荐
相关产品推荐

