6

I've found a couple of others asking for help with this, but not specifically what I'm trying to do. I have a dictionary full of various formats (int, str, bool, etc) and I'm trying to save it so I can load it at a later time. Here is a basic version of the code without all the extra trappings that are irrelevant for this.

petStats = { 'name':"", 'int':1, 'bool':False }

def petSave(pet):
    with open(pet['name']+".txt", "w+") as file:
        for k,v in pet.items():
            file.write(str(k) + ':' + str(v) + "\n")

def digimonLoad(petName):
    dStat = {}
    with open(petName+".txt", "r") as file:
        for line in file:
            (key, val) = line.split(":")
            dStat[str(key)] = val
    print(petName,"found. Loading",petName+".")
    return dStat

In short I'm just brute forcing it by saving a text file with a Key:Value on each line, then split them all back up on load. Unfortunately this turns all of my int and bool into strings. Is there a file format I could use to save a dictionary to (I don't need to be able to read it, but the conveniance would be nice) that I could easily load back in?

This works for a basic dictionary but if I start adding things like arrays this is going to get out of hand as it is.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
MiuKujo
  • 233
  • 1
  • 2
  • 8

4 Answers4

6

Use module json.

import json

def save_pet(pet):
    filename = <Whatever filename you want>
    with open(filename, 'w') as f:
        f.write(json.dumps(pet))

def load_pet(filename):
    with open(filename) as f:
        pet = json.loads(f.read())
    return pet
Roland Smith
  • 42,427
  • 3
  • 64
  • 94
cylee
  • 550
  • 6
  • 21
  • Great solution if the contents of the dictionary can be converted into json, but this will not work with other python objects that can't be converted to json. – knowledge_seeker Aug 15 '21 at 00:38
6

Use pickle. This is part of the standard library, so you can just import it.

import pickle

pet_stats = {'name':"", 'int':1, 'bool':False}

def pet_save(pet):
    with open(pet['name'] + '.pickle', 'wb') as f:
        pickle.dump(pet, f, pickle.HIGHEST_PROTOCOL)

def digimon_load(pet_name):
    with open(pet_name + '.pickle', 'rb') as f:
        return pickle.load(f)

Pickle works on more data types than JSON, and automatically loads them as the right Python type. (There are ways to save more types with JSON, but it takes more work.) JSON (or XML) is better if you need the output to be human-readable, or need to share it with non-Python programs, but neither appears to be necessary for your use case. Pickle will be easiest.

If you need to see what's in the file, just load it using Python or

python -m pickle foo.pickle

instead of a text editor. (Only do this to pickle files from sources you trust, pickle is not at all secure against hacking.)

gilch
  • 10,813
  • 1
  • 23
  • 28
3

Q: Is there a file format I could use to save a dictionary to load back in?

A: Yes, there are many. XML and JSON come immediately to mind.

For example:

jsonfile.txt

 {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}

Here's an example reading the file into a dictionary:

import json

with open('data.txt','r') as json_file:
   data = json.load(json_file)

... and an example writing the dictionary to JSON:

import json
with open('data.txt','w') as fp:
    fp.write(json.dumps(data))

If you prefer XML, there are many libraries, including xmltodict:

import xmltodict

with open('path/to/file.xml') as fd:
    doc = xmltodict.parse(fd.read())
Trees
  • 1,245
  • 10
  • 20
paulsm4
  • 114,292
  • 17
  • 138
  • 190
1

There are two useful words that you may not know about yet : serialization and pickle.

Serialization refers to the process of converting a data structure (like your dictionary) to a stream of bytes that can be written to storage, and later retrieved from storage to recreate that data structure. This is a common task and your intuition is correct: trying to do this all by yourself will quickly get out of hand.

Pickle is the standard python module for implementing serialization. It’s easy to use, mature and works with a large set of Python data types. You can read more about pickle here : https://docs.python.org/3/library/pickle.html

Wilf Rosenbaum
  • 518
  • 3
  • 10
  • 1
    It doesn't actually work on all Python data types. Try pickling a lambda. See [what can be pickled and unpickled](https://docs.python.org/3/library/pickle.html#what-can-be-pickled-and-unpickled) – gilch Aug 18 '19 at 04:48
  • Thanks @gilch. I have edited my comment. It was my fault for doing a hasty reading of the pickle vs json documentation. – Wilf Rosenbaum Aug 18 '19 at 04:56