我正在使用
我该怎么办?我可以看到以下选择:
1. 找到所有当前和未来客户端代码中执行映射查找的实例,并将其转换为
defaultdict(set)
来填充一个非常大的数据结构中的内部映射。填充完成后,整个结构(包括映射)都会暴露给客户端代码。此时,我不希望任何人修改映射。即使是有意无意地引用不存在的元素,正常字典会引发KeyError
异常,但由于映射是defaultdict
,它只会在该键处创建一个新元素(一个空集)。这很难捕捉,因为一切都是在默默无闻中发生。但我需要确保这不会发生(实际上,语义并没有被破坏,但映射会增长到一个巨大的大小)。我该怎么办?我可以看到以下选择:
1. 找到所有当前和未来客户端代码中执行映射查找的实例,并将其转换为
mapping.get(k, {})
。这太可怕了。
2. 在数据结构完全初始化后“冻结”defaultdict
,通过将其转换为dict
来实现。(我知道它并没有真正被冻结,但我相信客户端代码实际上不会编写mapping[k] = v
。)不优雅,性能损失很大。
3. 将defaultdict
包装成一个dict
接口。有什么优雅的方法可以做到这一点吗?但我担心性能损失会很大(在紧密循环中广泛使用此查找)。
4. 子类化defaultdict
并添加一个方法,该方法“关闭”所有defaultdict
功能,使其表现得好像它是一个常规的dict
。这是上述第3种方法的变体,但我不确定它是否更快。而且我不知道是否可以在不依赖于实现细节的情况下完成。使用普通的dict
数据结构,在重写所有代码之前,首先检查元素是否在字典中,如果不在,则将其添加。这样做不够好。
dict.setdefault
方法即可... 没什么大不了的。 - JBernardodefaultdict
上调用dict
来将其转换为字典。 - inspectorG4dgetdefaultdict
的论点吗?(我并不反对,只是想理解逻辑。) - maxdict
将会发生)太昂贵了。 - maxdict.setdefault
是用C实现的,它和defaultdict.__getitem__
做的事情完全一样。它不应该同样快吗? - max