Search code examples
pythonsaveshelve

How to save/load data with shelve using a "for" loop?


I'm trying to use shelve to save/load some data to/from a file. I have a list of dictionaries:

inv = [slot0, slot1, slot2, slot3, slot4, slot5, slot6]

And each of the 7 dictionaries look like this, but with slight variation in the values:

slot0 = {"item_pos": [hud_x + 592, hud_y + 4], "text_pos": [hud_x + 612, hud_y + 25], "item": None, "amount": 0}

In order to save/load the dictionaries, I use the "shelve" module, and here is the code for saving:

with shelve.open((os.path.join(saves_path, "inventory", "inventory")), "c") as f:

        f["slot0_item"] = slot0["item"]
        f["slot0_amount"] = slot0["amount"]
        f["slot1_item"] = slot1["item"]
        f["slot1_amount"] = slot1["amount"]
        f["slot2_item"] = slot2["item"]
        f["slot2_amount"] = slot2["amount"]
        f["slot3_item"] = slot3["item"]
        f["slot3_amount"] = slot3["amount"]
        f["slot4_item"] = slot4["item"]
        f["slot4_amount"] = slot4["amount"]
        f["slot5_item"] = slot5["item"]
        f["slot5_amount"] = slot5["amount"]
        f["slot6_item"] = slot6["item"]
        f["slot6_amount"] = slot6["amount"]

Here is the code for loading:

with shelve.open((os.path.join(saves_path, "inventory", "inventory")), "c") as f:

        slot0["item"] = f["slot0_item"]
        slot0["amount"] = f["slot0_amount"]
        slot1["item"] = f["slot1_item"]
        slot1["amount"] = f["slot1_amount"]
        slot2["item"] = f["slot2_item"]
        slot2["amount"] = f["slot2_amount"]
        slot3["item"] = f["slot3_item"]
        slot3["amount"] = f["slot3_amount"]
        slot4["item"] = f["slot4_item"]
        slot4["amount"] = f["slot4_amount"]
        slot5["item"] = f["slot5_item"]
        slot5["amount"] = f["slot5_amount"]
        slot6["item"] = f["slot6_item"]
        slot6["amount"] = f["slot6_amount"]

While this code works fine, it's very long and inefficient. I tried to use a "for" loop to save the data like this:

for slot in inv:
            f["slot_item"] = slot["item"]
            f["slot_amount"] = slot["amount"]

...And load the data like this:

for slot in inv:
            slot["item"] = f["slot_item"]
            slot["amount"] = f["slot_amount"]

However, when I use this method, the dictionaries don't save/load their changes when restarting the program, like they're supposed to. How can I (if it's possible) correctly use a "for" loop to efficiently save/load data with shelve?

EDIT: hud_x and hud_y both equal 20


Solution

  • I've decided to use pickle instead, since it more easily works with "for" loops. Also, shelve uses dictionary-like syntax (pickle doesn't), so that may have been part of the issue.

    Saving:

    with open((os.path.join(saves_path, "inventory", "inventory.txt")), "wb") as f:
            for slot in inv:
                pickle.dump(slot["item"], f)
                pickle.dump(slot["amount"], f)
    

    Loading:

    with open((os.path.join(saves_path, "inventory", "inventory.txt")), "rb") as f:
            for slot in self.inventory.inv:
                slot["item"] = pickle.load(f)
                slot["amount"] = pickle.load(f)