解析期间是否可以将ConfigParser选项转换为类型?

时间:2019-07-04 15:08:45

标签: python-3.x jinja2

使用ConfigParser实例时,可以通过其getintgetfloat和{{1 }} 方法。通过为构造函数的getboolean命名参数传递适当的值,可以扩展支持的类型的列表。

因此显式的效果很好。

现在考虑以下脚本,其中包含一个converters文件和一个内联的Jinja2模板:

.ini

输出为:

#!/usr/bin/env python3
import sys
assert sys.version_info[:2] >= (3, 5), "Need at least Python 3.5"
from configparser import ConfigParser
from io import StringIO
from jinja2 import Template

INI_FILE = """\
[section]
option1 = yes
option2 = no"""

TPL_FILE = """\
From loop:
{% for opt in cfg.options("section") -%}
{{ opt }} = {{ cfg.get("section", opt) }}
{% endfor -%}
Directly:
option1 = {{ cfg.section.option1 }}
option2 = {{ cfg.section.option2 }}
real true = {{ realt }}
real false = {{ realf }}
"""

if __name__ == "__main__":
    cfg = ConfigParser()
    cfgfile = StringIO(INI_FILE)
    cfg.read_file(cfgfile)
    # cfg["section"]["option3"] = True <- must be string
    # cfg["section"]["option4"] = False <- ditto
    tpl = Template(TPL_FILE)
    print(tpl.render(cfg=cfg, realt=True, realf=False))

现在,无论如何访问From loop: option1 = yes option2 = no Directly: option1 = yes option2 = no real true = True real false = False option1,我都将如何将它们视为布尔值,就像我以名称option2和{{1 }}?

realt似乎将所有内容都视为字符串。

我看到两种方法可以实现我想要的。

  1. 一种方法是编写一个Jinja2过滤器,该过滤器接受允许使用的各种字符串形式(并且显然由getboolean()识别)
  2. 另一种方法可能是派生realf并以某种方式实现此行为。

但是,看到方法1会重复代码(并且我的代码不会随ConfigParser中的代码自动更改,因此可以想象实现会有所不同);而且方法2最终可能会在多个地方重复信息,我想知道Python的电池供电方法是否包含我所缺少的那种东西。

如何使ConfigParserConfigParsergetset知道标准类型(__setitem____getitem__,{{ 1}})受int支持?我在这里还缺少什么其他方法?

1 个答案:

答案 0 :(得分:0)

现在,我正在准备一个自定义的Jinja2过滤器,该过滤器将字符串值作为输入并使用ConfigParser将其解析为布尔值。不过,我觉得它很丑,并且仍然希望看到其他人的更好答案。

def my_filter(optvalue):
    assert isinstance(optvalue, str), "We expect only string values as input from ConfigParser"
    from configparser import ConfigParser, DEFAULTSECT
    cfg = ConfigParser()
    cfg.read_string("[%s]\n%s = %s\n" % (DEFAULTSECT, DEFAULTSECT, optvalue))
    return cfg.getboolean(DEFAULTSECT, DEFAULTSECT)

我现在可以这样做(假设过滤器已注册为asbool):

option2 = {{ cfg.section.option2|asbool }}

...或在以下情况下:

{% if cfg.section.option2|asbool %}
something ...
{% endif %}