Можно ли преобразовать параметры ConfigParser в тип во время анализа? - PullRequest
1 голос
/ 04 июля 2019

При использовании экземпляра ConfigParser возможно явное преобразование параметра в тип с помощью методов getint, getfloat и getboolean,И список поддерживаемых типов можно расширить, передав соответствующее значение для converters именованного аргумента конструктора.

Так явно работает хорошо.

Теперь рассмотрим следующий скрипт, содержащий.ini файл и встроенный шаблон Jinja2:

#!/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 обращаются, ониобрабатываются как логические значения, точно так же, как действительные логические значения, которые я передаю под именами realt и realf соответственно?

ConfigParser, кажется, рассматривает все как строку.

Я вижудва способа добиться того, чего я хочу.

  1. Один из них - написать фильтр Jinja2, который принимает различные строковые формы, разрешенные к использованию (и, очевидно, распознается getboolean())
  2. Другой метод может состоять в том, чтобы получить ConfigParser и каким-то образом реализовать это поведение.

Однако, увидев, что метод 1 будет дублировать код (и мой код не изменится автоматическикод в ConfigParser, поэтому реализации могут предположительно расходиться);и этот метод 2 может также привести к дублированию информации в нескольких местах, мне интересно, есть ли в подходе Python с включенным аккумулятором что-то вроде того, чего мне не хватает.

Как я могу сделать get, set и __setitem__, __getitem__ в курсе стандартных типов (int, float, boolean), поддерживаемых ConfigParser?Какие еще методы мне здесь не хватает?

1 Ответ

0 голосов
/ 05 июля 2019

Сейчас я согласен с пользовательским фильтром 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 %}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...