Question

It's well-documented that Python's shelve module requires all keys to be strings and that there are various workarounds (see threads here and here). My question is, why does shelve require string keys? Given that I can pickle a dict that uses other objects as keys, and that shelve uses pickle under the hood, why can't shelve handle such keys itself? Do string keys make it vastly simpler to update only a piece of the persistent object rather than having to rewrite the whole thing (and if so, why)?

Était-ce utile?

La solution

Because under the hood the shelve module uses one of bsddb, gdbm or dbm for storage, and they support only string keys.

You're right that you can pickle a dict that uses other objects as keys, but then when one key changes, you have to flush the whole storage. By using a key-value database like those, only the changed values are flushed.

Autres conseils

May be somebody will find this example useful

class Data:
    __slots__ = "name", "version"

    def __init__(self, name, version):
        self.name, self.version = name, version

    def __str__(self):
        return f"{self.name}:{self.version}"


    def encode(self, *args):
        s = self.__str__()
        return s.encode(*args)


def _d(s: str) -> Data:
    words = s.split(":")
    return Data(words[0], words[1]) 

import shelve
db = shelve.open("./db", flag="n", writeback=False)
print(Data("1", "2") in db)
for key in db:
    print(f"{_d(key)}")
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top