ソリューションの唯一の本当の問題は、シェルフが値をピクルして保存することです。そのため、ディスクにページオフするたびに、第 2 レベルの辞書のそれぞれをピクルしてピクルを解除する必要があり、パフォーマンスが大幅に低下する可能性があります。(もちろん、各第 2 レベルの dict はメモリに収まる必要がありますが、それはおそらく問題ではありません。)
それが問題でなければ、あなたがしていることは問題ありません。しかし、そうであれば、他に 2 つの選択肢があります。
棚上げよりも複雑なデータベースを使用して、その周りに独自のラッパーを構築できます。
または、はるかに単純です。ペアをキーとして単一レベルの辞書を使用するだけです。
def create_entry(key1, key2, value, shelf):
shelf[(key1, key2)] = value
これの欠点は、たとえば、サブディクショナリ内のすべてのキーまたは値を反復する必要がある場合、key1
シェルフ全体を反復する必要があることです。それほど複雑ではありませんが ( (key2 for key1, key2 in shelf if key1 == key)
)、かなり遅くなります。
shelve
キーは文字列でなければならないため、上記のコードは実際には では直接機能しません。しかし、それをまとめる非常に簡単な方法があります。値を pickle および unpickle するのと同じようshelve
に、キーを文字列化して解析するよりもラッパーを書くことができます。
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
str
shelve
def _mapkey(self, key):
return struct.pack('>II', key)
def _unmapkey(self, key):
return struct.unpack('<II', key)