Hanfei Sun
Hanfei Sun

Reputation: 47051

Convert dict into a config file then restore the dict from config

For example, I have a dictionary in Python like this:

{"a_summary" : 
   {"data1":{"length":100, "quality":10}, 
    "data2":{"length":90, "quality":9}},
"b_summary" :  
   {"data1":{"comments":19, "views":100}, 
    "data2":{"comments":9, "views":4}}}

And then I'd like to convert it into a conf file like this:

[a_summary]
data1_length=100
data1_quality=10
data2_length=90
data2_quality=9

[b_summary]
data1_comments=19
data1_views=100
data2_comments=9
data2_views=4

Though it looks a little weird that data1_ or data2_ is need to represent the nesting, it seems ok now.

But then I need to send this conf file to another user, and he needs to restore the original dictionary from this conf file. It seems that user has to write a few more codes for restoring the dict. However, this solution looks quite dirty.

I was wondering whether there's a Pythonic way for me to save dict into a conf file (if conf file is not suitable, other readable format of plain text is also acceptable) and then restore dict from that plain text file.

Upvotes: 5

Views: 6096

Answers (5)

cowlinator
cowlinator

Reputation: 8813

It's possible to do this without loops or 3rd party modules.

This will work no matter how deep the dictionary is.

from configparser import ConfigParser

data = {"a_summary" : {"data1":{"length":100, "quality":10}, 
            "data2":{"length":90, "quality":{"q1":1, "q2":{"am": "high", "pm": "low"}}}},
        "b_summary" :  {"data1":{"comments":19, "views":100}, 
            "data2":{"comments":9, "views":4}}}

# dict -> ConfigParser
config = ConfigParser()
config.read_dict(data)
with open('example.ini', 'w') as configfile:
    config.write(configfile)
    
# check result
with open('example.ini', 'r') as configfile2:
    print(configfile2.read())

# ConfigParser -> dict
config2 = ConfigParser()
config2.read('example.ini')
data2 = {section: dict(config2[section]) for section in config2.sections()}
print(data2)

Upvotes: 1

Noname
Noname

Reputation: 6033

In case of .ini files, you could use configobj module. To read:

from configobj import ConfigObj
dict = ConfigObj(path)

To save:

from configobj import ConfigObj
config = ConfigObj(dict)
config.filename = "config.ini"
config.write()

Upvotes: 1

Charles Brunet
Charles Brunet

Reputation: 23120

Look at configparser module. It could help you to do what you want.

import configparser

data = {"a_summary" : {"data1":{"length":100, "quality":10}, 
            "data2":{"length":90, "quality":9}},
        "b_summary" :  {"data1":{"comments":19, "views":100}, 
            "data2":{"comments":9, "views":4}}}
config = configparser.ConfigParser()
for key1, data1 in data.items():
    config[key1] = {}
    for key2, data2 in data1.items():
        for key3, data3 in data2.items():
            config[key1]["{}_{}".format(key2, key3)] = str(data3)
with open('example.ini', 'w') as configfile:
    config.write(configfile)

And to read again:

config2 = configparser.ConfigParser()
config2.read('example.ini')
data = {}
for key in config2.sections():
    data[key] = {}
    for key2 in config2[key]:
        k1, k2 = key2.split('_')
        if k1 not in data[key]:
            data[key][k1] = {}
        data[key][k1][k2] = int(config2[key][key2])

Upvotes: 7

John Zwinck
John Zwinck

Reputation: 249273

Just write it out as JSON and restore it from the same. It'll still be very readable, and it will easily support basic data structures beyond what the "INI" syntax will.

Upvotes: -1

Martijn Pieters
Martijn Pieters

Reputation: 1122322

Save it as JSON perhaps:

import json

with open('configfilename', 'w') as configfile:
    json.dump(yourdict, configfile, indent=2)

I set the json.dump() indentation to make the file reasonably readable.

Load with:

import json

with open('configfilename', 'r') as configfile:
    yourdict = json.load(configfile)

With indent set to 2, your structure would be written out as:

{
  "a_summary": {
    "data1": {
      "length": 100, 
      "quality": 10
    }, 
    "data2": {
      "length": 90, 
      "quality": 9
    }
  }, 
  "b_summary": {
    "data1": {
      "comments": 19, 
      "views": 100
    }, 
    "data2": {
      "comments": 9, 
      "views": 4
    }
  }
}

Upvotes: 5

Related Questions