You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 16:15:02