argparse - определяет пользовательские действия или типы с дополнительными аргументами - PullRequest
0 голосов
/ 23 ноября 2018

Я разрабатываю набор инструментов, содержащий несколько сценариев Python.Для некоторых из них некоторые аргументы могут быть числовыми значениями.В зависимости от сценария некоторые могут требовать, чтобы значение v составляло от -1 до 1, или от 0 до 1, или от 1 до 10, или ... Примером может быть ширина страницы из выходной диаграммы, которая всегда должна быть положительной.

Я могу все время проверять, находится ли v в требуемом диапазоне.Я также мог бы для каждого из этих диапазонов определить Action или тип, используя argparse.Пример приведен с использованием нового типа:

def positive_num(a_value):
    """Check a numeric positive."""
    if not a_value > 0:
        raise argparse.ArgumentTypeError("Should be positive.")
    return a_value 

и добавьте его позже в синтаксический анализатор:

parser_grp.add_argument('-pw', '--page-width',
                        help='Output pdf file width (e.g. 7 inches).',
                        type=positive_num,
                        default=None,
                        required=False)

Теперь, если значение является коэффициентом корреляции (или чем-либо в диапазоне) было бы возможно использовать действие или типы, чтобы написать что-то более общее, используя:

def ranged_num(a_value, lowest=-1, highest=1):
    """Check a numeric is in expected range."""
    if not (a_value >= lowest and a_value <= highest):
        raise argparse.ArgumentTypeError("Not in range.")
    return a_value 

Это можно было бы позже добавить как:

parser_grp.add_argument('-c', '--correlation',
                        help='A value for the correlation coefficient',
                        type=ranged_num(-1,1),
                        default=None,
                        required=False)

Я пробовал несколькими способами, но без успеха.

Спасибо

1 Ответ

0 голосов
/ 23 ноября 2018

За документация :

type= может принять любой вызываемый объект, который принимает один строковый аргумент и возвращает преобразованное значение

Поэтому, чтобы использовать его как type=ranged_num(-1,1), ваша ranged_num функция должна возвращать саму функцию .Функция, которая возвращает функцию (или принимает функцию в качестве аргумента, или и то, и другое), часто называется «функцией более высокого порядка».

Вот минимальный пример:

def ranged_num(lowest=-1, highest=1):
    """Check a numeric is in expected range."""
    def type_func(a_value):
        a_value = int(a_value)  # or "float"; you could also have error handling here
        if not (a_value >= lowest and a_value <= highest):  # I'd rewrite this to an "or"
            raise argparse.ArgumentTypeError("Not in range.")
        return a_value
    return type_func

Теперь ranged_num создает и возвращает функцию type_func, которая отвечает за обработку строки, поступающей из командной строки.

...