您的解决方案唯一真正的问题是架子通过腌制它们来存储值,因此每次将第二级字典分页到磁盘时都必须对其进行腌制和取消腌制,这可能会产生巨大的性能成本。(当然,每个二级字典都必须适合内存,但这可能不是问题。)
如果这无关紧要,那么你所做的一切都很好。但如果是这样,还有其他两种选择。
您可以使用一些比搁置更复杂的数据库并围绕它构建自己的包装器。
或者,更简单:只需使用带有对作为键的单级字典:
def create_entry(key1, key2, value, shelf):
shelf[(key1, key2)] = value
这样做的缺点是,如果您需要,例如,迭代子字典中的所有键或值,则key1
必须迭代整个架子。它并不完全复杂((key2 for key1, key2 in shelf if key1 == key)
),但它会慢很多。
上面的代码实际上并不能直接用于shelve
,因为键必须是字符串。但是有很简单的方法可以结束它。就像shelve
pickles 和 unpickles 值一样,您可以编写一个包装器而不是字符串化和解析键 - 例如:
def _mapkey(self, key):
return ','.join(map(str, key))
def _unmapkey(self, key):
return tuple(map(int, key.split(',')))
def __getitem__(self, key):
return self.shelf[self._mapkey(key)]
def __iter__(self):
return map(self._unmapkey, self.shelf)
# etc.
为了提高效率,最好分叉或子类化shelve
,这样您就可bytes
以为底层dbm
密钥生成 a,而不是生成 astr
以便shelve
对其进行编码。然后你可以这样做:
def _mapkey(self, key):
return struct.pack('>II', key)
def _unmapkey(self, key):
return struct.unpack('<II', key)