【问题标题】:Converting ConfigParser values to python data types将 ConfigParser 值转换为 python 数据类型
【发布时间】:2011-06-02 00:04:42
【问题描述】:

ConfigParser 要求所有部分、键和值都是字符串;没有惊喜。它具有将值转换为具有getfloatgetintgetboolean 的数据类型的方法。如果您不知道数据类型,可以将 get()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,但我真的很想保持配置文件可读。

你会怎么做?

【问题讨论】:

    标签: python eval configparser


    【解决方案1】:

    如果您使用的是 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
    

    【讨论】:

    【解决方案2】:

    对于那些可能正在寻找另一个更简单的答案的人,您可以使用为您进行转换的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

    【讨论】:

    • 谢谢,您的包裹对我很有帮助!
    【解决方案3】:

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

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

    from ast import literal_eval
    import configparser
    
    parser = configparser.ConfigParser(converters={"any": lambda x: literal_eval(x)})
    value = parser.getany("section", "key")
    # ...
    

    【讨论】:

      【解决方案4】:

      如果您使用的是 2.7+,那么您可以使用 .getint .getfloat .getbool 方法。您可以在docs 中了解更多信息

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

      【讨论】:

        【解决方案5】:

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

        https://github.com/barberj/ConfigIt

        【讨论】:

          猜你喜欢
          • 2017-05-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多