在python中从配置文件读取数组
我有个问题。我的程序使用配置文件来设置选项,其中一个选项是元组。我的意思是:在python中从配置文件读取数组,python,configuration-files,tuples,Python,Configuration Files,Tuples,我有个问题。我的程序使用配置文件来设置选项,其中一个选项是元组。我的意思是: [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模块将其解析为元组吗?有什么简单的方法可以做到这一点吗?我不知道Confi
[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模块将其解析为元组吗?有什么简单的方法可以做到这一点吗?我不知道ConfigParser,但您可以轻松地将其读入列表(可能使用
.append()
),然后执行myTuple=tuple(myList)
您可以获得项目列表,并使用列表理解来创建名称以定义的前缀开头的所有项目的列表,在您的案例文件夹中
您的配置可以是:
[common]
logfile=log.txt
db_host=localhost
db_user=root
db_pass=password
folder = ("/home/scorpil", "/media/sda5/", "/media/sdb5/")
假设在名为foo.cfg的文件中有config,则可以执行以下操作:
import ConfigParser
cp = ConfigParser.ConfigParser()
cp.read("foo.cfg")
folder = eval(cp.get("common", "folder"), {}, {})
print folder
print type(folder)
应产生:
(“/home/scorpil”“,“/media/sda5/”,“/media/sdb5/”)--编辑--
后来我改变了主意,今天我的立场是,在这种情况下使用eval是个坏主意。即使在受限环境中,如果配置文件在用户控制下,这可能是一个非常糟糕的主意。今天,我可能会建议您使用split进行一些有趣的操作,以避免恶意代码执行。如果您可以像这样更改配置格式:
#!/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"))
folder = /home/scorpil
/media/sda5/
/media/sdb5/
然后在python中:
config.get("common", "folder").split("\n")
创建配置:
folders = ['/home/scorpil', '/media/sda5/', '/media/sdb5/']
config.set('common', 'folders', json.dumps(folders))
tuple(json.loads(config.get('common', 'folders')))
负载配置:
folders = ['/home/scorpil', '/media/sda5/', '/media/sdb5/']
config.set('common', 'folders', json.dumps(folders))
tuple(json.loads(config.get('common', 'folders')))
您可以完全坚持使用json
tst.json
{
"common": {
"logfile":"log.txt",
"db_host":"localhost",
"db_user":"root",
"db_pass":"password",
"folder": [
"/home/scorpil",
"/media/sda5/",
"/media/sdb5/"
]
}
}
那就用它吧
$ 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/')
此解决方案假定文件中的条目顺序正确。@Terrel Shumway是这样做的,但您始终可以事先对项目进行排序。事先排序没有帮助:文件夹[10]<文件夹[2]我同意通常eval()是不好的。在控制输入并限制执行环境的情况下,这是一个可接受的解决方案。更安全地使用eval()的关键是确保已为eval()指定了全局和局部参数。有关更多详细信息,请参阅。