Reading array from config file in python
Asked Answered
A

7

9

I have a problem. My program is using config file to set options, and one of those options is a tuple. Here's what i mean:

[common]
logfile=log.txt
db_host=localhost
db_user=root
db_pass=password
folder[1]=/home/scorpil
folder[2]=/media/sda5/
folder[3]=/media/sdb5/

etc... Can i parse this into tuple with ConfigParser module in Python? Is there some easy way to do this?

Ahab answered 4/11, 2010 at 13:31 Comment(0)
V
14

if you can change config format like this:

folder = /home/scorpil
         /media/sda5/
         /media/sdb5/

then in python:

config.get("common", "folder").split("\n")
Varga answered 2/7, 2012 at 15:26 Comment(0)
P
6

Your config could be:

[common]
logfile=log.txt
db_host=localhost
db_user=root
db_pass=password
folder = ("/home/scorpil", "/media/sda5/", "/media/sdb5/")

Assuming that you have config in a file named foo.cfg, you can do the following:

import ConfigParser
cp = ConfigParser.ConfigParser()
cp.read("foo.cfg")
folder = eval(cp.get("common", "folder"), {}, {})

print folder
print type(folder)

which should produce:

('/home/scorpil', '/media/sda5/', '/media/sdb5/')
<type 'tuple'>

-- EDIT -- I've since changed my mind about this, and would take the position today that using eval in this context is a bad idea. Even with a restricted environment, if the configuration file is under user control it may be a very bad idea. Today I'd probably recommend doing something interesting with split to avoid malicious code execution.

Pelpel answered 4/11, 2010 at 13:50 Comment(2)
I would agree that in general eval() is not good. In the case where you control the input, and restrict the execution environment it is an acceptable solution.Pelpel
Evil no, gobsmackingly dangerous yes. The key to safer use of eval() is to ensure that you have specified the global and local parameters to eval(). See docs.python.org/2/library/functions.html#eval for more details.Pelpel
S
4

Create configuration:

folders = ['/home/scorpil', '/media/sda5/', '/media/sdb5/']
config.set('common', 'folders', json.dumps(folders))

Load configuration:

tuple(json.loads(config.get('common', 'folders')))
Scrutiny answered 19/12, 2017 at 16:43 Comment(0)
L
3

You can get the items list and use a list comprehension to create a list of all the items which name starts with a defined prefix, in your case folder

folders = tuple([ item[1] for item in configparser.items() if item[0].startswith("folder")])
Limicoline answered 4/11, 2010 at 13:35 Comment(3)
This solution assumes that the entries in the file are in the proper order.Dao
@Terrel Shumway is does but you could always sort the items beforehand.Limicoline
sorting beforehand won't help: folder[10] < folder[2]Dao
O
1

I don't know ConfigParser, but you can easily read it into a list (perhaps using .append()) and then do myTuple = tuple(myList)

Ovate answered 4/11, 2010 at 13:35 Comment(0)
D
1
#!/usr/bin/env python
sample = """
[common]
logfile=log.txt
db_host=localhost
db_user=root
db_pass=password
folder[1]=/home/scorpil
folder[2]=/media/sda5/
folder[3]=/media/sdb5/
"""
from cStringIO import StringIO
import ConfigParser
import re
FOLDER_MATCH = re.compile(r"folder\[(\d+)\]$").match

def read_list(items,pmatch=FOLDER_MATCH):
    if not hasattr(pmatch,"__call__"):
        pmatch = re.compile(pmatch).match
    folder_list = []
    for k,v in items:
        m = pmatch(k)
        if m:
            folder_list.append((int(m.group(1)),v))
    return tuple( kv[1] for kv in sorted(folder_list) )


if __name__ == '__main__':
    cp = ConfigParser.SafeConfigParser()
    cp.readfp(StringIO(sample),"sample")

    print read_list(cp.items("common"))
Dao answered 4/11, 2010 at 14:51 Comment(0)
E
1

You could stick to json completely

tst.json

{
  "common": {
    "logfile":"log.txt",
    "db_host":"localhost",
    "db_user":"root",
    "db_pass":"password",
    "folder": [
      "/home/scorpil",
      "/media/sda5/",
      "/media/sdb5/"
    ]
  }
}

then work with it

$ python3

>>> import json
>>> with open("tst.json", "r", encoding="utf8") as file_object:
...   job = json.load(file_object)
... 
>>> job
{'common': {'db_pass': 'password', 'logfile': 
'log.txt', 'db_user': 'root', 'folder': 
['/home/scorpil', '/media/sda5/', '/media/sdb5/'], 
'db_host': 'localhost'}}

>>> print (job["common"]["folder"][0])
/home/scorpil
>>> print (job["common"]["folder"][1])
/media/sda5/
print (job["common"]["folder"][2])
/media/sdb5/

>>> folder_tuple = tuple(job["common"]["folder"])
>>> folder_tuple
('/home/scorpil', '/media/sda5/', '/media/sdb5/')
Erickericka answered 13/2, 2021 at 23:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.