在ConfigParser中列出

pis*_*hio 158 python configparser

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

[Section]
bar=foo
[Section 2]
bar2= baz
Run Code Online (Sandbox Code Playgroud)

现在,有没有办法索引列表,例如:

[Section 3]
barList={
    item1,
    item2
}
Run Code Online (Sandbox Code Playgroud)

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

qua*_*odo 205

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

[Foo]
fibs: [1,1,2,3,5,8,13]
Run Code Online (Sandbox Code Playgroud)

只需阅读:

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

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

[Bar]
files_to_check = [
     "/path/to/file1",
     "/path/to/file2",
     "/path/to/another file with space in the name"
     ]
Run Code Online (Sandbox Code Playgroud)

当然我可以使用JSON,但我发现配置文件更具可读性,[DEFAULT]部分非常方便.

  • 你必须有["a","b","c"]字符串才能使它们起作用.对我来说,这点击了数字,但因为cfg文件大多是可编辑的 - 每次添加""都很痛苦.我宁愿用逗号然后分开它. (4认同)
  • 这对于原始字符串如何工作,例如`key5 : [r"abc $x_i$", r"def $y_j$"]`?他们提出错误`json.decoder.JSONDecodeError: Expecting value: line 1 column 2 (char 1)` (3认同)
  • Python 3.6 引发错误:json.decoder.JSONDecodeError:期望值:第 1 行第 2 列(字符 1) (2认同)

Dav*_*cke 127

没有什么能阻止您将列表打包成分隔的字符串,然后在从配置中获取字符串后将其解压缩.如果您这样做,您的配置部分将如下所示:

[Section 3]
barList=item1,item2
Run Code Online (Sandbox Code Playgroud)

它并不漂亮,但它适用于大多数简单列表.

  • 这就是Python日志配置文件的工作方式. (9认同)
  • 如果您有复杂的列表,可以参考这个问题:http://stackoverflow.com/questions/330900/how-to-quickly-parse-a-list-of-strings :-) (2认同)
  • 如果列表只有一个元素怎么办? (2认同)

Hen*_*oke 92

迟到了这个派对,但我最近在配置文件中使用专用部分实现了这个列表:

[paths]
path1           = /some/path/
path2           = /another/path/
...
Run Code Online (Sandbox Code Playgroud)

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

path_items = config.items( "paths" )
for key, path in path_items:
    #do something with path
Run Code Online (Sandbox Code Playgroud)

希望这有助于其他民间谷歌搜索这个问题;)

  • @AlexDean您可以通过设置optionxform = str来设置ConfigParser以使camelCase保持原位.示例:`config = ConfigParser.SafeConfigParser()``config.optionxform = str`然后案件将一个人留下 (4认同)
  • 我喜欢这个解决方案,因为你可以`; 注释掉列表中的某些项目,而不必重写整个列表. (3认同)
  • @DevPlayer 使用多键时,您只能获得最后一个值。(为了其他读者的利益,回应 2 岁的评论) (3认同)

Pet*_*mit 58

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

;test.ini
[hello]
barlist = 
    item1
    item2
Run Code Online (Sandbox Code Playgroud)

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

"\nitem1\nitem2"
Run Code Online (Sandbox Code Playgroud)

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

如果我们看一下像Pyramid这样的大框架他们正在使用这种技术:

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
Run Code Online (Sandbox Code Playgroud)

资源

我自己,如果这对你来说很常见,我可能会扩展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)]
Run Code Online (Sandbox Code Playgroud)

请注意,使用此技术时需要注意一些事项

  1. 作为项目的新行应以空格开头(例如空格或制表符)
  2. 以空格开头的所有后续行都被视为前一项的一部分.如果它有一个=符号或者它以a开头; 跟随空白.

  • .split()在所有空格中断(除非给出特定字符),.splitlines()在所有换行符上中断. (7认同)

Pyt*_*ter 34

如果你想直接传入一个列表,那么你可以使用:

ast.literal_eval()
Run Code Online (Sandbox Code Playgroud)

例如配置:

[section]
option=["item1","item2","item3"]
Run Code Online (Sandbox Code Playgroud)

代码是:

import ConfigParser
import ast

my_list = ast.literal_eval(config.get("section", "option"))
print(type(my_list))
print(my_list)
Run Code Online (Sandbox Code Playgroud)

输出:

<type'list'>
["item1","item2","item3"]
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,与使用(可以说更流行)“json.loads()”相比,使用“ast.literal_eval()”有什么优势?我认为后者提供了更多的安全性,不是吗? (3认同)
  • 我希望看到并举例说明,如果您认为有帮助,可以随时在此主题中添加答案,尽管您的评论本身会是一个很好的问题。我给出的答案简化了ConfigParser中列表的使用,因此在应用程序内部是消除了使用正则表达式的麻烦。没有上下文,我无法评论其“安全”价值。 (2认同)

Joh*_*Mee 15

我来这里寻求消费......

[global]
spys = richard.sorge@cccp.gov, mata.hari@deutschland.gov
Run Code Online (Sandbox Code Playgroud)

答案是将其拆分为逗号并删除空格:

SPYS = [e.strip() for e in parser.get('global', 'spys').split(',')]
Run Code Online (Sandbox Code Playgroud)

要获得列表结果:

['richard.sorge@cccp.gov', 'mata.hari@deutschland.gov']
Run Code Online (Sandbox Code Playgroud)

它可能无法准确回答OP的问题,但可能是一些人正在寻找的简单答案.

  • 我以为迪克在`sorger @ espionage.su`!难怪我的邮件不断跳动!&gt; _ &lt; (2认同)

Grr*_*Grr 15

在任何这些答案中都没有提到converterskwargConfigParser()是相当令人失望的.

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

example.ini

[Germ]
germs: a,list,of,names, and,1,2, 3,numbers
Run Code Online (Sandbox Code Playgroud)

解析器示例:

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']
Run Code Online (Sandbox Code Playgroud)

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

  • 最佳答案在这里。它使用 ConfigParser 已经提供的内容。没有额外的包、方法、类...... (4认同)

Lit*_*ter 10

这是我用于列表的内容:

配置文件内容:

[sect]
alist = a
        b
        c
Run Code Online (Sandbox Code Playgroud)

代码:

l = config.get('sect', 'alist').split('\n')
Run Code Online (Sandbox Code Playgroud)

它适用于字符串

如果是数字

配置内容:

nlist = 1
        2
        3
Run Code Online (Sandbox Code Playgroud)

码:

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

谢谢.


fee*_*per 7

我在我的项目中完成了类似的任务,其中包含没有值的键:

import configparser

# allow_no_value param says that no value keys are ok
config = configparser.ConfigParser(allow_no_value=True)

# overwrite optionxform method for overriding default behaviour (I didn't want lowercased keys)
config.optionxform = lambda optionstr: optionstr

config.read('./app.config')

features = list(config['FEATURES'].keys())

print(features)
Run Code Online (Sandbox Code Playgroud)

输出:

['BIOtag', 'TextPosition', 'IsNoun', 'IsNomn']
Run Code Online (Sandbox Code Playgroud)

应用程序配置:

[FEATURES]
BIOtag
TextPosition
IsNoun
IsNomn
Run Code Online (Sandbox Code Playgroud)


小智 7

所以我更喜欢的另一种方法是拆分值,例如:

#/path/to/config.cfg
[Numbers]
first_row = 1,2,4,8,12,24,36,48
Run Code Online (Sandbox Code Playgroud)

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

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(',')]
Run Code Online (Sandbox Code Playgroud)

此方法可防止您将值包装在方括号中以作为 JSON 加载。