在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)] 
请注意,使用这种技术时有几件事情需要注意
- 作为项目的新行应以空格开头(例如空格或制表符)
- 所有以空格开头的行都被认为是前一项的一部分。 另外,如果它有一个=符号,或者如果它开始于一个; 跟着空白。
如果你想从字面上传递一个列表,那么你可以使用:
 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工作。