Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 596
Hanfei Sun Avatar asked Apr 12 '13 11:04

Hanfei Sun


4 Answers

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])
like image 59
Charles Brunet Avatar answered Nov 01 '22 20:11

Charles Brunet


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
    }
  }
}
like image 20
Martijn Pieters Avatar answered Nov 01 '22 20:11

Martijn Pieters


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()
like image 1
Noname Avatar answered Nov 01 '22 18:11

Noname


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)
like image 1
cowlinator Avatar answered Nov 01 '22 20:11

cowlinator