The typical ConfigParser generated file looks like:
[Section]
bar=foo
[Section 2]
bar2= baz
Now, is there a way to index lists like, for in
I completed similar task in my project with section with keys without values:
import configparser
# allow_no_value param says that no value keys are ok
config = configparser.ConfigParser(allow_no_value=True)
# overwrite optionxform method for overriding default behaviour (I didn't want lowercased keys)
config.optionxform = lambda optionstr: optionstr
config.read('./app.config')
features = list(config['FEATURES'].keys())
print(features)
Output:
['BIOtag', 'TextPosition', 'IsNoun', 'IsNomn']
app.config:
[FEATURES]
BIOtag
TextPosition
IsNoun
IsNomn
There is nothing stopping you from packing the list into a delimited string and then unpacking it once you get the string from the config. If you did it this way your config section would look like:
[Section 3]
barList=item1,item2
It's not pretty but it's functional for most simple lists.
If you want to literally pass in a list then you can use:
ast.literal_eval()
For example configuration:
[section]
option=["item1","item2","item3"]
The code is:
import ConfigParser
import ast
my_list = ast.literal_eval(config.get("section", "option"))
print(type(my_list))
print(my_list)
output:
<type'list'>
["item1","item2","item3"]
Coming late to this party, but I recently implemented this with a dedicated section in a config file for a list:
[paths]
path1 = /some/path/
path2 = /another/path/
...
and using config.items( "paths" )
to get an iterable list of path items, like so:
path_items = config.items( "paths" )
for key, path in path_items:
#do something with path
Hope this helps other folk Googling this question ;)
import ConfigParser
import os
class Parser(object):
"""attributes may need additional manipulation"""
def __init__(self, section):
"""section to retun all options on, formatted as an object
transforms all comma-delimited options to lists
comma-delimited lists with colons are transformed to dicts
dicts will have values expressed as lists, no matter the length
"""
c = ConfigParser.RawConfigParser()
c.read(os.path.join(os.path.dirname(__file__), 'config.cfg'))
self.section_name = section
self.__dict__.update({k:v for k, v in c.items(section)})
#transform all ',' into lists, all ':' into dicts
for key, value in self.__dict__.items():
if value.find(':') > 0:
#dict
vals = value.split(',')
dicts = [{k:v} for k, v in [d.split(':') for d in vals]]
merged = {}
for d in dicts:
for k, v in d.items():
merged.setdefault(k, []).append(v)
self.__dict__[key] = merged
elif value.find(',') > 0:
#list
self.__dict__[key] = value.split(',')
So now my config.cfg
file, which could look like this:
[server]
credentials=username:admin,password:$3<r3t
loggingdirs=/tmp/logs,~/logs,/var/lib/www/logs
timeoutwait=15
Can be parsed into fine-grained-enough objects for my small project.
>>> import config
>>> my_server = config.Parser('server')
>>> my_server.credentials
{'username': ['admin'], 'password', ['$3<r3t']}
>>> my_server.loggingdirs:
['/tmp/logs', '~/logs', '/var/lib/www/logs']
>>> my_server.timeoutwait
'15'
This is for very quick parsing of simple configs, you lose all ability to fetch ints, bools, and other types of output without either transforming the object returned from Parser
, or re-doing the parsing job accomplished by the Parser class elsewhere.
This is what I use for lists:
config file content:
[sect]
alist = a
b
c
code :
l = config.get('sect', 'alist').split('\n')
it work for strings
in case of numbers
config content:
nlist = 1
2
3
code:
nl = config.get('sect', 'alist').split('\n')
l = [int(nl) for x in nl]
thanks.