在ConfigParser列表

典型的ConfigParser生成文件如下所示:

[Section] bar=foo [Section 2] bar2= baz 

现在,有没有一种方法来索引列表,例如:

 [Section 3] barList={ item1, item2 } 

相关的问题: 每个部分Python的ConfigParser唯一键

? 提前致谢

没有任何东西阻止你将列表打包成分隔string,然后在从configuration中获取string时将其解包。 如果你这样做,你的configuration部分将如下所示:

 [Section 3] barList=item1,item2 

这不是很漂亮,但它对大多数简单的列表是有用的。

也有点晚,但也许对一些有帮助。 我正在使用ConfigParser和JSON的组合:

 [Foo] fibs: [1,1,2,3,5,8,13] 

只读:

 >>> json.loads(config.get("Foo","fibs")) [1, 1, 2, 3, 5, 8, 13] 

如果列表很长,你甚至可以断行(谢谢@ peter-smit):

 [Bar] files_to_check = [ "/path/to/file1", "/path/to/file2", "/path/to/another file with space in the name" ] 

当然,我可以使用JSON,但我发现configuration文件更可读,[DEFAULT]部分非常方便。

这次晚会迟到了,但是我最近在一个configuration文件中为一个列表实现了这个专门的部分:

 [paths] path1 = /some/path/ path2 = /another/path/ ... 

并使用config.items( "paths" )获取path项的迭代列表,如下所示:

 path_items = config.items( "paths" ) for key, path in path_items: #do something with path 

希望这有助于其他民众谷歌search这个问题;)

有很多人不知道的是,多线configuration值是允许的。 例如:

 ;test.ini [hello] barlist = item1 item2 

config.get('hello','barlist')现在是:

 "\nitem1\nitem2" 

您可以轻松地使用拆分方法拆分(不要忘记过滤空项目)。

如果我们看一下象金字塔那样的大框架,他们正在使用这种技术:

 def aslist_cronly(value): if isinstance(value, string_types): value = filter(None, [x.strip() for x in value.splitlines()]) return list(value) def aslist(value, flatten=True): """ Return a list of strings, separating the input based on newlines and, if flatten=True (the default), also split on spaces within each line.""" values = aslist_cronly(value) if not flatten: return values result = [] for value in values: subvalues = value.split() result.extend(subvalues) return result 

资源

我自己,如果这是你常见的事情,我可能会扩展ConfigParser:

 class MyConfigParser(ConfigParser): def getlist(self,section,option): value = self.get(section,option) return list(filter(None, (x.strip() for x in value.splitlines()))) def getlistint(self,section,option): return [int(x) for x in self.getlist(section,option)] 

请注意,使用这种技术时有几件事情需要注意

  1. 作为项目的新行应以空格开头(例如空格或制表符)
  2. 所有以空格开头的行都被认为是前一项的一部分。 另外,如果它有一个=符号,或者如果它开始于一个; 跟着空白。

如果你想从字面上传递一个列表,那么你可以使用:

 ast.literal_eval() 

例如configuration:

 [section] option=["item1","item2","item3"] 

代码是:

 import ConfigParser import ast my_list = ast.literal_eval(config.get("section", "option")) print(type(my_list)) print(my_list) 

输出:

 <type'list'> ["item1","item2","item3"] 

我在这里降落,试图消耗这个…

 [global] spys = richard.sorge@cccp.gov, mata.hari@deutschland.gov 

答案是将其拆分为逗号并去掉空格:

 SPYS = [e.strip() for e in parser.get('global', 'spys').split(',')] 

得到一个列表结果:

 ['richard.sorge@cccp.gov', 'mata.hari@deutschland.gov'] 

它可能不完全回答OP的问题,但可能是一些人正在寻找的简单答案。

这是我用于列表的:

configuration文件内容:

 [sect] alist = a b c 

代码:

 l = config.get('sect', 'alist').split('\n') 

它适用于string

在数字的情况下

configuration内容:

 nlist = 1 2 3 

码:

 nl = config.get('sect', 'alist').split('\n') l = [int(nl) for x in nl] 

谢谢。

configurationparsing器只支持原始types的序列化。 我会使用JSON或YAML来满足这种需求。

我过去也面临同样的问题。 如果您需要更复杂的列表,请考虑通过从ConfigParserinheritance来创build您自己的parsing器。 然后你会覆盖get方法:

  def get(self, section, option): """ Get a parameter if the returning value is a list, convert string value to a python list""" value = SafeConfigParser.get(self, section, option) if (value[0] == "[") and (value[-1] == "]"): return eval(value) else: return value 

有了这个解决scheme,你也可以在configuration文件中定义字典。

不过要小心! 这是不安全的:这意味着任何人都可以通过你的configuration文件运行代码。 如果安全性不是你的项目中的问题,我会考虑直接使用python类作为configuration文件。 以下是比ConfigParser文件更强大和更耗费的:

 class Section bar = foo class Section2 bar2 = baz class Section3 barList=[ item1, item2 ] 
 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(',') 

所以现在我的config.cfg文件,看起来像这样:

 [server] credentials=username:admin,password:$3<r3t loggingdirs=/tmp/logs,~/logs,/var/lib/www/logs timeoutwait=15 

可以parsing成我的小项目足够细粒度的对象。

 >>> 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' 

这是为了快速parsing简单的configuration,在不转换从Parser返回的对象的情况下,您将失去获取ints,bools和其他types的输出的所有能力,或者重新执行parsing器类在其他地方完成的parsing工作。