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

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

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

[Section 3]
barList={
    item1,
    item2
}

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


当前回答

很多人不知道的一件事是允许多行配置值。例如:

;test.ini
[hello]
barlist = 
    item1
    item2

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

"\nitem1\nitem2"

你可以很容易地用splitlines方法进行分割(不要忘记过滤空项)。

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

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)]

注意,在使用这种技术时需要注意一些事情

作为项目的新行应该以空格开始(例如空格或制表符) 下面所有以空格开头的行都被认为是前一项的一部分。如果它有一个=号或者如果它以a开头;跟着空格。

其他回答

这些回答中没有提到ConfigParser()的转换器kwarg,这令人相当失望。

根据文档,您可以向ConfigParser传递一个字典,它将为解析器和节代理添加一个get方法。对于列表:

example.ini

[Germ]
germs: a,list,of,names, and,1,2, 3,numbers

解析器的例子:

cp = ConfigParser(converters={'list': lambda x: [i.strip() for i in x.split(',')]})
cp.read('example.ini')
cp.getlist('Germ', 'germs')
['a', 'list', 'of', 'names', 'and', '1', '2', '3', 'numbers']
cp['Germ'].getlist('germs')
['a', 'list', 'of', 'names', 'and', '1', '2', '3', 'numbers']

这是我个人最喜欢的,因为不需要子类化,我不需要依赖最终用户来完美地编写JSON或可以由ast.literal_eval解释的列表。

很多人不知道的一件事是允许多行配置值。例如:

;test.ini
[hello]
barlist = 
    item1
    item2

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

"\nitem1\nitem2"

你可以很容易地用splitlines方法进行分割(不要忘记过滤空项)。

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

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)]

注意,在使用这种技术时需要注意一些事情

作为项目的新行应该以空格开始(例如空格或制表符) 下面所有以空格开头的行都被认为是前一项的一部分。如果它有一个=号或者如果它以a开头;跟着空格。

我更喜欢的另一种方法,就是分割这些值,例如:

#/path/to/config.cfg
[Numbers]
first_row = 1,2,4,8,12,24,36,48

可以像这样加载到字符串或整数列表中,如下所示:

import configparser

config = configparser.ConfigParser()
config.read('/path/to/config.cfg')

# Load into a list of strings
first_row_strings = config.get('Numbers', 'first_row').split(',')

# Load into a list of integers
first_row_integers = [int(x) for x in config.get('Numbers', 'first_row').split(',')]

这种方法可以避免将值包装在括号中以JSON形式加载。

如果这是你的config.ini:

[Section 3]
barList=item1,item2

然后使用configparser你可以这样做:

from configparser import ConfigParser
config = ConfigParser()
config.read('config.ini')
my_list = config['Section 3']['barList'].split(',')

你会得到:

 my_list =  ['item1', 'item2']

split()方法将返回一个列表,参见Python字符串文档。

如果你在config.ini中有空格,像这样:

[Section 3]
barList= item1, item2

那你最好这样做:

my_list = [x.strip() for x in config['Section 3']['barList'].split(',')]

如果你的项目是数字(例如整数),只需应用:

my_list_of_ints = list(map(int, my_list))

你会得到:

my_list_of_ints =  [item1, item2]

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

ast.literal_eval()

举例配置:

[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"]