在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工作。