2010-11-04 1320 views
5

我遇到问题。我的程序使用配置文件来设置选项,其中一个选项是元组。这就是我的意思是:从python配置文件中读取数组

[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/ 

等... 我可以解析为元组里面可以用Python configparser模块用来?有没有一些简单的方法来做到这一点?

回答

8

如果你可以改变配置的格式是这样的:

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

则:

config.get("common", "folder").split("\n") 
1

我不知道ConfigParser,但你可以很容易地读取到一个列表(可能使用.append()),然后做myTuple = tuple(myList)

3

你可以得到的物品清单,并使用列表解析创建所有列表其名称与定义的前缀开始的项目,你的情况文件夹

folders = tuple([ item[1] for item in configparser.items() if item[0].startswith("folder")]) 
+0

此解决方案假定文件中的条目处于正确的顺序。 – 2010-11-04 14:51:25

+0

@Terrel Shumway可以,但您可以事先对物品进行分类。 – Rod 2010-11-04 15:46:07

+0

预先排序不会帮助:文件夹[10] <文件夹[2] – 2010-11-04 21:26:26

4

你的配置可能是:

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

假设你有一个文件名为foo.cfg配置,你可以做到以下几点:

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

print folder 
print type(folder) 

应该产生:

( '/家庭/ scorpil',“/媒体/ SDA5 /”, '/媒体/ sdb5 /')
<型 '元组' >

- 编辑 - 因为我已经改变了主意此事,并会TA今天的立场是,在这种情况下使用eval是一个坏主意。即使在受限制的环境下,如果配置文件受用户控制,这可能是一个非常糟糕的主意。今天,我可能会建议做一些有趣的事情,以避免恶意代码执行。

+0

有一个点,这帮助我出局 – cacois 2012-03-23 20:01:18

+4

eval()解决方案不好,一般来说。 – 2012-05-18 23:02:27

+0

我同意一般eval()不好。在您控制输入并限制执行环境的情况下,这是一个可接受的解决方案。 – 2012-05-20 16:30:06

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")) 
1

创建配置:

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

加载配置文件:

tuple(json.loads(config.get('common', 'folders')))