我正在使用defaultdict(set)在非常大的数据结构中填充内部映射。填充后,整个结构(包括映射)将暴露给客户端代码。那时,我不希望任何人修改映射。
没有人故意这样做。但有时,客户端代码可能会意外引用不存在的元素。那时,一个普通的字典会产生KeyError,但由于映射是defaultdict,它只是在该键处创建一个新元素(一个空集)。这很难捕捉,因为一切都在悄无声息地发生。但我需要确保不会发生这种情况(语义实际上不会中断,但映射会增长到巨大的大小)。
我该怎么办?我可以看到这些选择:
在当前和未来的客户端代码中查找对映射执行字典查找的所有实例,并将其转换为
mapping.get(k, {})。这太可怕了。defaultdict在数据结构完全初始化后“冻结” ,将其转换为dict. (我知道它并没有真正冻结,但我相信客户端代码实际上不会编写mapping[k] = v。)不优雅,并且性能受到很大影响。包装
defaultdict成一个dict界面。有什么优雅的方法来做到这一点?恐怕性能损失可能很大(这种查找在紧密循环中大量使用)。子类
defaultdict化并添加一个“关闭”所有defaultdict功能的方法,让它的行为就好像它是一个常规的dict. 它是上述 3 的变体,但我不确定它是否更快。如果不依赖实现细节,我不知道它是否可行。在数据结构中使用正则
dict,重写那里的所有代码以首先检查元素是否在字典中,如果不在则添加。不好。