Python如何O(1)批量修改类实例__getitem__使用的索引映射函数
最优实现方案
核心思路是引入实例分组层,所有共用同一套映射规则的实例绑定到同一个分组对象,修改分组的映射配置即可批量生效,时间复杂度为O(1),同时尽可能缩短__getitem__的调用链路保证性能。
代码实现
# 可复用的映射分组类 class MapGroup: def __init__(self, map_func): self.map_func = map_func # 恒等映射作为默认分组 default_group = MapGroup(lambda index: index) class MyObject: def __init__(self, data, map_group=default_group): self.data = data # 实例仅持有分组引用,不直接存映射函数 self.map_group = map_group def __getitem__(self, index): # 调用链路极短,性能损耗极低 return self.data[self.map_group.map_func(index)] # ---------------------- 使用示例 ---------------------- # 1. 定义映射函数 def map1(index): return index[0] + index[1] def map2(index): return index[0] * index[1] def map3(index): return index[0] + 10 * index[1] # 2. 创建分组 p_group = MapGroup(map1) q_group = MapGroup(map2) # 3. 初始化实例,绑定对应分组 p1 = MyObject(range(1000), p_group) p2 = MyObject(range(1000), p_group) q1 = MyObject(range(1000), q_group) q2 = MyObject(range(1000), q_group) # 需求1:把p组所有实例的映射从map1切到map2,O(1)操作 p_group.map_func = map2 # 需求2:把p、q组所有实例都切到map2,O(1)操作 q_group.map_func = map2 # 需求3:把所有实例切到map3,O(1)操作 p_group.map_func = map3 q_group.map_func = map3 # 额外需求:全局所有用map3的实例切到map4,用可调用对象包装即可实现O(1)替换 class CallableMap: def __init__(self, func): self.func = func def __call__(self, index): return self.func(index) # 用包装器包裹map3,所有分组引用同一个包装器实例 map3_wrapper = CallableMap(map3) p_group.map_func = map3_wrapper q_group.map_func = map3_wrapper # 全局替换map3为map4,仅需修改包装器的内部函数,O(1)生效 map4 = lambda index: index[0] + 20 * index[1] map3_wrapper.func = map4
方案优势
- 所有批量切换映射的操作都是纯O(1),完全不需要遍历实例
__getitem__仅多了一次属性查找,性能损耗可以忽略,完全满足高频调用的需求- 没有重复的映射副本,同一个映射函数/可调用对象仅需存储一次
- 扩展性强,支持任意层级的分组嵌套,满足更复杂的批量管理需求
内容的提问来源于stack exchange,提问作者vand
相关产品推荐
相关产品推荐

