Python如何给自定义类加方法实现基于source_id的点语法访问
结论先行
直接实现mydata.1.source_desc这种写法是不可能的:Python语法要求合法的属性名(标识符)只能由字母、数字、下划线组成,且不能以数字开头,数字开头的属性写法会直接触发SyntaxError,属于解释器层面的语法限制,没有任何方案可以绕过。
以下是符合「不依赖列表索引、仅用source_id作为访问入口」要求的可行替代方案:
方案1:加统一前缀适配点语法
给source_id统一加固定前缀(比如id_)即可符合Python属性命名规则,最终调用形式为mydata.id_1.source_desc,完全满足点语法访问的需求。
# 数据条目包装类,用于实现字段的点语法访问 class DataItem: def __init__(self, item_dict): for k, v in item_dict.items(): setattr(self, k, v) class ddata(): # 修正原类__init__方法遗漏self参数的问题 def __init__(self, var): raw_data = self.method_class(var) self._data_map = {} for item in raw_data: source_id = item['source_id'] self._data_map[source_id] = DataItem(item) # 生成带前缀的属性,支持点语法访问 setattr(self, f"id_{source_id}", self._data_map[source_id]) def method_class(self, v): '''do stuff / dummy method''' return v
测试效果:
d=[{'source_id': '1', 'source_desc': 'XML1'}, {'source_id': '2', 'source_desc': 'XML2'}, {'source_id': '3', 'source_desc': 'XML3'}] mydata = ddata(d) print(mydata.id_1.source_desc) # 输出XML1
方案2:下标访问(写法更贴近原需求)
如果不想加前缀,可以实现__getitem__魔法方法,用mydata['1'].source_desc的形式调用,同时兼容字符串/数字类型的source_id:
class DataItem: def __init__(self, item_dict): for k, v in item_dict.items(): setattr(self, k, v) class ddata(): def __init__(self, var): raw_data = self.method_class(var) self._data_map = {} for item in raw_data: source_id = item['source_id'] self._data_map[source_id] = DataItem(item) # 同时存储数字类型key,兼容数字id查询 if source_id.isdigit(): self._data_map[int(source_id)] = self._data_map[source_id] def method_class(self, v): '''do stuff / dummy method''' return v def __getitem__(self, key): return self._data_map[key]
测试效果:
d=[{'source_id': '1', 'source_desc': 'XML1'}, {'source_id': '2', 'source_desc': 'XML2'}, {'source_id': '3', 'source_desc': 'XML3'}] mydata = ddata(d) print(mydata['1'].source_desc) # 输出XML1 print(mydata[2].source_desc) # 输出XML2,支持数字类型id查询
内容的提问来源于stack exchange,提问作者JFerro
相关产品推荐
相关产品推荐

