Read all the contents in ini file into dictionary with Python
Question:
Normally, I code as follows for getting a particular item in a variable as follows
try:
config = ConfigParser.ConfigParser()
config.read(self.iniPathName)
except ConfigParser.MissingSectionHeaderError, e:
raise WrongIniFormatError(`e`)
try:
self.makeDB = config.get("DB","makeDB")
except ConfigParser.NoOptionError:
self.makeDB = 0
Is there any way to read all the contents in a python dictionary?
For example
[A]
x=1
y=2
z=3
[B]
x=1
y=2
z=3
is written into
val["A"]["x"] = 1
...
val["B"]["z"] = 3
Answers:
I managed to get an answer, but I expect there should be a better one.
dictionary = {}
for section in config.sections():
dictionary[section] = {}
for option in config.options(section):
dictionary[section][option] = config.get(section, option)
The instance data for ConfigParser is stored internally as a nested dict. Instead of recreating it, you could just copy it.
>>> import ConfigParser
>>> p = ConfigParser.ConfigParser()
>>> p.read("sample_config.ini")
['sample_config.ini']
>>> p.__dict__
{'_defaults': {}, '_sections': {'A': {'y': '2', '__name__': 'A', 'z': '3', 'x': '1'}, 'B': {'y': '2', '__name__': 'B', 'z': '3', 'x': '1'}}, '_dict': <type 'dict'>}
>>> d = p.__dict__['_sections'].copy()
>>> d
{'A': {'y': '2', '__name__': 'A', 'z': '3', 'x': '1'}, 'B': {'y': '2', '__name__': 'B', 'z': '3', 'x': '1'}}
Edit:
Alex Martelli’s solution is cleaner, more robust, and prettier. While this was the accepted answer, I’d suggest using his approach instead. See his comment to this solution for more info.
I suggest subclassing ConfigParser.ConfigParser
(or SafeConfigParser
, &c) to safely access the “protected” attributes (names starting with single underscore — “private” would be names starting with two underscores, not to be accessed even in subclasses…):
import ConfigParser
class MyParser(ConfigParser.ConfigParser):
def as_dict(self):
d = dict(self._sections)
for k in d:
d[k] = dict(self._defaults, **d[k])
d[k].pop('__name__', None)
return d
This emulates the usual logic of config parsers, and is guaranteed to work in all versions of Python where there’s a ConfigParser.py
module (up to 2.7, which is the last of the 2.*
series — knowing that there will be no future Python 2.any versions is how compatibility can be guaranteed;-).
If you need to support future Python 3.*
versions (up to 3.1 and probably the soon forthcoming 3.2 it should be fine, just renaming the module to all-lowercase configparser
instead of course) it may need some attention/tweaks a few years down the road, but I wouldn’t expect anything major.
How to parse ini file in py?
import ConfigParser
config = ConfigParser.ConfigParser()
config.read('/var/tmp/test.ini')
print config.get('DEFAULT', 'network')
Where test.ini file contain:
[DEFAULT]
network=shutup
others=talk
I know that this question was asked 5 years ago, but today I’ve made this dict comprehension thingy:
parser = ConfigParser()
parser.read(filename)
confdict = {section: dict(parser.items(section)) for section in parser.sections()}
One more thing to take care is, ConfigParser
converts the key values to lowercase hence in case you are converting the config entries to a dictionary cross check your requirements. I faced a problem because of this. For me I was having camel-case keys hence, had to change some amount of code when I started using the dictionary instead of files. ConfigParser.get()
method internally converts the key to lower-case.
from https://wiki.python.org/moin/ConfigParserExamples
def ConfigSectionMap(section):
dict1 = {}
options = Config.options(section)
for option in options:
try:
dict1[option] = Config.get(section, option)
if dict1[option] == -1:
DebugPrint("skip: %s" % option)
except:
print("exception on %s!" % option)
dict1[option] = None
return dict1
suppose file: config.properties contains the following:
- k =v
- k2= v2
- k3= v3
python code:
def read_config_file(file_path):
with open(file=file_path, mode='r') as fs:
return {k.strip(): v.strip() for i in [l for l in fs.readlines() if l.strip() != ''] for k, v in [i.split('=')]}
print('file as dic: ', read_config_file('config.properties'))
Normally, I code as follows for getting a particular item in a variable as follows
try:
config = ConfigParser.ConfigParser()
config.read(self.iniPathName)
except ConfigParser.MissingSectionHeaderError, e:
raise WrongIniFormatError(`e`)
try:
self.makeDB = config.get("DB","makeDB")
except ConfigParser.NoOptionError:
self.makeDB = 0
Is there any way to read all the contents in a python dictionary?
For example
[A] x=1 y=2 z=3 [B] x=1 y=2 z=3
is written into
val["A"]["x"] = 1 ... val["B"]["z"] = 3
I managed to get an answer, but I expect there should be a better one.
dictionary = {}
for section in config.sections():
dictionary[section] = {}
for option in config.options(section):
dictionary[section][option] = config.get(section, option)
The instance data for ConfigParser is stored internally as a nested dict. Instead of recreating it, you could just copy it.
>>> import ConfigParser
>>> p = ConfigParser.ConfigParser()
>>> p.read("sample_config.ini")
['sample_config.ini']
>>> p.__dict__
{'_defaults': {}, '_sections': {'A': {'y': '2', '__name__': 'A', 'z': '3', 'x': '1'}, 'B': {'y': '2', '__name__': 'B', 'z': '3', 'x': '1'}}, '_dict': <type 'dict'>}
>>> d = p.__dict__['_sections'].copy()
>>> d
{'A': {'y': '2', '__name__': 'A', 'z': '3', 'x': '1'}, 'B': {'y': '2', '__name__': 'B', 'z': '3', 'x': '1'}}
Edit:
Alex Martelli’s solution is cleaner, more robust, and prettier. While this was the accepted answer, I’d suggest using his approach instead. See his comment to this solution for more info.
I suggest subclassing ConfigParser.ConfigParser
(or SafeConfigParser
, &c) to safely access the “protected” attributes (names starting with single underscore — “private” would be names starting with two underscores, not to be accessed even in subclasses…):
import ConfigParser
class MyParser(ConfigParser.ConfigParser):
def as_dict(self):
d = dict(self._sections)
for k in d:
d[k] = dict(self._defaults, **d[k])
d[k].pop('__name__', None)
return d
This emulates the usual logic of config parsers, and is guaranteed to work in all versions of Python where there’s a ConfigParser.py
module (up to 2.7, which is the last of the 2.*
series — knowing that there will be no future Python 2.any versions is how compatibility can be guaranteed;-).
If you need to support future Python 3.*
versions (up to 3.1 and probably the soon forthcoming 3.2 it should be fine, just renaming the module to all-lowercase configparser
instead of course) it may need some attention/tweaks a few years down the road, but I wouldn’t expect anything major.
How to parse ini file in py?
import ConfigParser
config = ConfigParser.ConfigParser()
config.read('/var/tmp/test.ini')
print config.get('DEFAULT', 'network')
Where test.ini file contain:
[DEFAULT]
network=shutup
others=talk
I know that this question was asked 5 years ago, but today I’ve made this dict comprehension thingy:
parser = ConfigParser()
parser.read(filename)
confdict = {section: dict(parser.items(section)) for section in parser.sections()}
One more thing to take care is, ConfigParser
converts the key values to lowercase hence in case you are converting the config entries to a dictionary cross check your requirements. I faced a problem because of this. For me I was having camel-case keys hence, had to change some amount of code when I started using the dictionary instead of files. ConfigParser.get()
method internally converts the key to lower-case.
from https://wiki.python.org/moin/ConfigParserExamples
def ConfigSectionMap(section):
dict1 = {}
options = Config.options(section)
for option in options:
try:
dict1[option] = Config.get(section, option)
if dict1[option] == -1:
DebugPrint("skip: %s" % option)
except:
print("exception on %s!" % option)
dict1[option] = None
return dict1
suppose file: config.properties contains the following:
- k =v
- k2= v2
- k3= v3
python code:
def read_config_file(file_path):
with open(file=file_path, mode='r') as fs:
return {k.strip(): v.strip() for i in [l for l in fs.readlines() if l.strip() != ''] for k, v in [i.split('=')]}
print('file as dic: ', read_config_file('config.properties'))