Python中能否区分赋值的变量引用与取值行为以实现模糊字典?
核心结论
Python 原生没有提供机制区分 __getitem__ 的调用场景是赋值左侧的左值引用,还是赋值右侧的取值操作。所有 fd[key] 形式的访问都会无差别触发 __getitem__ 方法,你无法直接在方法内部判断当前调用的使用场景。
可行解决方案
这里提供两种落地思路,可根据你的使用场景选择:
方案1:返回代理对象实现双行为
你可以让 __getitem__ 返回一个包装了「单键真实存储值」和「模糊合并结果」的代理类,代理类针对不同操作实现对应逻辑:
- 读取类操作(打印、迭代、取长度、普通集合运算)返回模糊合并的结果
- 修改类操作(
|=、add、remove等)直接作用到对应单键的真实存储值上
示例代码框架:
class FuzzyValueProxy: def __init__(self, fuzzy_dict, target_key): self.fd = fuzzy_dict self.key = target_key # 预计算模糊合并结果用于读取场景 self.fuzzy_val = self._get_fuzzy_val() def _get_fuzzy_val(self): res = set() # 相邻键计算逻辑可根据你的需求调整 for dx, dy in [(-1,0), (0,-1), (0,0), (0,1), (1,0)]: nbr_key = (self.key[0]+dx, self.key[1]+dy) if nbr_key in self.fd.innerdict: res |= self.fd.innerdict[nbr_key] return res # 读取相关魔法方法,返回模糊结果 def __repr__(self): return repr(self.fuzzy_val) def __iter__(self): return iter(self.fuzzy_val) def __len__(self): return len(self.fuzzy_val) def __or__(self, other): return self.fuzzy_val | other # 修改相关魔法方法,作用到真实存储的单键值上 def __ior__(self, other): self.fd.innerdict[self.key] |= other return self def add(self, item): self.fd.innerdict[self.key].add(item) class FuzzyDict: def __init__(self): self.innerdict = {} def __getitem__(self, key): return FuzzyValueProxy(self, key) def __setitem__(self, key, value): self.innerdict[key] = set(value)
这种方案可以完全符合你想要的语法效果,但缺点是隐式行为较多,其他使用该类的开发者容易混淆逻辑,排查bug的成本更高。
方案2:拆分普通取值和模糊查询方法(更推荐)
这种方案完全避免隐式行为,逻辑清晰易维护:
- 保留默认的
__getitem__仅返回对应单键的真实存储值,用于赋值、修改场景 - 单独实现
fuzzy_get(key)方法返回相邻键的合并结果,用于需要模糊查询的场景
示例逻辑:
class FuzzyDict: def __init__(self): self.innerdict = {} def __getitem__(self, key): # 直接返回单键真实值,用于修改场景 return self.innerdict[key] def __setitem__(self, key, value): self.innerdict[key] = set(value) def fuzzy_get(self, key): # 模糊查询返回合并结果 res = set() for dx, dy in [(-1,0), (0,-1), (0,0), (0,1), (1,0)]: nbr_key = (key[0]+dx, key[1]+dy) if nbr_key in self.innerdict: res |= self.innerdict[nbr_key] return res
使用时的语法区别如下:
# 修改单键值,逻辑无歧义 fd[(0,1)] |= {x10} # 模糊查询调用明确的方法 print(fd.fuzzy_get((0,0)))
内容的提问来源于stack exchange,提问作者Haydon Berrow
相关产品推荐
相关产品推荐

