如何在ConfigArgParse中执行多行列表?

时间:2019-03-19 09:38:58

标签: python-3.x config

我有一个包含以下内容的配置文件。

[Default]
file_list = ['dataset1/*.wav', 'dataset2/*.wav', 'dataset3/*.wav', 
'dataset4/*.wav']

这是一个换行符,大多数时候都在Python中工作。我用这个解析

import configargparse
p = configargparse.ArgParser()
p.add('-c', '--my-config', required=True, is_config_file=True, help='config file path')
p.add('--file_list', action="append", required=False, help='path to genome file')
args = p.parse_args()

拨打适当的电话

python file.py --my-config=config.ini

问题是(毫不奇怪):

file.py: error: unrecognized arguments: --'dataset4/*.wav'] true

我认为这是因为期望在配置文件中有一个新的arg。 我还尝试了不同的行继续方法。

如何使用configargparse输入多个行列表?如果不能,配置文件列表输入的最小替代解决方案是什么?

1 个答案:

答案 0 :(得分:2)

我遇到了同样的问题。 我决定稍微修改默认解析器,然后创建支持多行的解析器。我只添加了几行代码。看起来像这样:

import configargparse
from collections import OrderedDict
import re


class LongLineConfigFileParser(configargparse.ConfigFileParser):
    """Based on a simplified subset of INI and YAML formats. Here is the
    supported syntax:


        # this is a comment
        ; this is also a comment (.ini style)
        ---            # lines that start with --- are ignored (yaml style)
        -------------------
        [section]      # .ini-style section names are treated as comments

        # how to specify a key-value pair (all of these are equivalent):
        name value     # key is case sensitive: "Name" isn't "name"
        name = value   # (.ini style)  (white space is ignored, so name = value same as name=value)
        name: value    # (yaml style)
        --name value   # (argparse style)

        # how to set a flag arg (eg. arg which has action="store_true")
        --name
        name
        name = True    # "True" and "true" are the same


        # how to specify a list arg (eg. arg which has action="append")
        fruit = [apple, orange, lemon]
        indexes = [1, 12, 35 , 40]

        # how to break a long line into multiple lines:
        fruit = [apple, \
        orage, \
        lemon]


    """

    def parse(self, stream):
        """Parses the keys + values from a config file."""
        items = OrderedDict()
        pre_line = '' # Used to support multiple lines
        for i, line in enumerate(stream):
            line = pre_line + line
            line = line.strip()
            if not line or line[0] in ["#", ";", "["] or line.startswith("---"):
                continue
            # Used to support multiple lines
            if line.endswith('\\'):
                pre_line = line.replace('\\', '').strip()
                continue
            else:
                pre_line = ''
            white_space = "\\s*"
            key = r"(?P<key>[^:=;#\s]+?)"
            value = white_space+r"[:=\s]"+white_space+"(?P<value>.+?)"
            comment = white_space+"(?P<comment>\\s[;#].*)?"

            key_only_match = re.match("^" + key + comment + "$", line)
            if key_only_match:
                key = key_only_match.group("key")
                items[key] = "true"
                continue

            key_value_match = re.match("^"+key+value+comment+"$", line)
            if key_value_match:
                key = key_value_match.group("key")
                value = key_value_match.group("value")

                if value.startswith("[") and value.endswith("]"):
                    # handle special case of lists
                    value = [elem.strip() for elem in value[1:-1].split(",")]

                items[key] = value
                continue

            raise configargparse.ConfigFileParserException("Unexpected line {} in {}: {}".format(i,
                getattr(stream, 'name', 'stream'), line))
        return items

要使用它,只需在调用ArgParser时添加config_file_parser_class=LongLineConfigFileParser

parser = configargparse.ArgParser(default_config_files=['DefaultParams.txt'],
                                  config_file_parser_class=LongLineConfigFileParser)

希望这会有所帮助