16

ConfigParser要求所有部分、键和值都是字符串;没有惊喜。它具有使用 , , 将值转换为数据类型getfloatgetint方法getboolean。如果您不知道数据类型,您可以get()用 an包装eval()来评估字符串,例如:

>>> from ConfigParser import SafeConfigParser
>>> cp = SafeConfigParser()
>>> cp.add_section('one')
>>> cp.set('one', 'key', '42')
>>> print cp.get('one', 'key')
'42'
>>> print eval(cp.get('one', 'key'))
42
>>> cp.set('one', 'key', 'None')
>>> print eval(cp.get('one', 'key'))
None
>>> 

有没有更好的办法?我认为评估文件中的文本存在一些严重的安全问题——我承认;我完全信任该文件。

我想我会用pickle这个,但我真的很想保持配置文件可读。

你会怎么做?

4

5 回答 5

16

如果您使用的是 Python 2.6 或更高版本,您可以使用ast.literal_eval

ast.literal_eval(node_or_string)
安全地评估表达式节点或包含 Python 表达式的字符串。提供的字符串或节点只能由以下 Python 文字结构组成:字符串、数字、元组、列表、字典、布尔值和无。

这可用于安全地评估来自不受信任来源的包含 Python 表达式的字符串,而无需自己解析值。

这将像eval字符串安全时一样工作:

>>> literal_eval("{'key': 10}")
{'key': 10}

但如果出现文档中列出的类型以外的任何内容,它将失败:

>>> literal_eval("import os; os.system('rm -rf somepath')")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.6/ast.py", line 49, in literal_eval
    node_or_string = parse(node_or_string, mode='eval')
  File "/usr/lib64/python2.6/ast.py", line 37, in parse
    return compile(expr, filename, mode, PyCF_ONLY_AST)
  File "<unknown>", line 1
    import os; os.system('rm -rf somepath')
         ^
SyntaxError: invalid syntax
于 2011-06-02T00:12:24.063 回答
4

对于那些可能正在寻找另一个更简单的答案的人,您可以使用为您进行转换的localconfig模块,而不必自己转换数据类型。转换是通过根据值猜测数据类型来完成的(即 123 是 int,123.4 是 float,true 是 bool,等等)。

以下是 OP 之后的示例:

>>> from localconfig import config
>>> config.read('[one]\nkey = 42\nkey2 = None')
>>> config.one.key, type(config.one.key)
(42, <type 'int'>)
>>> config.one.key2, type(config.one.key2)
(None, <type 'NoneType'>)
>>> config.get('one', 'key'), config.get('one', 'key2')
(42, None)

它是 ConfigParser 之上的一个包装器,因此它是完全兼容的。

在https://pypi.python.org/pypi/localconfig查看

于 2015-01-02T03:36:00.937 回答
4

这是另一种解决方案。您可以生成一个getany()方法,该方法将自动检测并返回大多数类型的正确数据类型,包括strint、和。floatboolNone

请注意,配置文件中的符号必须是 Python 才能工作。例如True对于布尔真值和None空值。

from ast import literal_eval
import configparser

parser = configparser.ConfigParser(converters={"any": lambda x: literal_eval(x)})
value = parser.getany("section", "key")
# ...
于 2021-02-10T21:33:10.330 回答
1

如果您使用的是 2.7+,那么您可以使用这些.getint .getfloat .getbool方法。您可以在文档中了解有关它们的更多信息

所以你的应用程序会使用print cp.getint('one', 'key')

于 2013-07-10T20:42:53.713 回答
0

查看 ConfigIt 以获得更多 pythonic 配置选项

https://github.com/barberj/ConfigIt

于 2014-02-10T02:35:04.677 回答