2016-06-10 2 views
1

Есть ли способ добавить аргумент в ArgumentParser для np.array вместо списка? Я знаю, что могу сделать что-то вроде этогоArgumentParser для numpy array

import argparse 
parser = argparse.ArgumentParser(prog='PROG') 
parser.add_argument('-foo', action='store', type=int, nargs='+') 
args = parser.parse_args(['-foo', '1', '2']) 
args.foo = np.array(args.foo) 

Но я хотел бы указать полное описание аргументов перед разбором.

Есть ли способ сделать это?

+1

Где бы вы описали "полное описание"? В командной строке или в настройке 'add_argument'? Дайте более подробный пример. – hpaulj

ответ

2

Чтобы задать небольшое изменение в том, как обработчик StoreAction действий работает вы бы создать subclass обработчика с соответствующим изменением (Документов есть пример прямо вышеthis section)

import argparse, numpy as np 

class Store_as_array(argparse._StoreAction): 
    def __call__(self, parser, namespace, values, option_string=None): 
     values = np.array(values) 
     return super().__call__(parser, namespace, values, option_string) 

parser = argparse.ArgumentParser(prog='PROG') 
parser.add_argument('-foo', action=Store_as_array, type=int, nargs='+') 
            #^specify as the action 
args = parser.parse_args(['-foo', '1', '2']) 

assert isinstance(args.foo, np.ndarray) 
+0

Это именно то, что я искал. Спасибо. – Tohiko

0

Как указаны в моем комментарий, «полное описание перед разбором» неясно.

Но мне пришло в голову, что можно создать массив 2d с argparse. Я могу использовать nargs=3, чтобы указать 3 столбца и action='append', чтобы собрать входные данные в нескольких подсписках. И, конечно, type указывает, будет ли он int или float.

In [27]: p=argparse.ArgumentParser() 

In [28]: p.add_argument('-a',action='append',nargs='+',type=int) 
Out[28]: _AppendAction(option_strings=['-a'], dest='a', nargs='+', const=None, default=None, type=<class 'int'>, choices=None, help=None, metavar=None) 

In [29]: args=p.parse_args('-a 1 2 3 -a 4 5 6 -a 7 8 9'.split()) 

In [30]: args 
Out[30]: Namespace(a=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]) 

In [31]: np.array(args.a) 
Out[31]: 
array([[1, 2, 3], 
     [4, 5, 6], 
     [7, 8, 9]]) 

Будет жаловаться, если у меня нет нужного количества столбцов. Все, что не контролируется, - это количество строк; но я могу легко проверить форму массива после создания.

С этим append не имеет смысла создавать массив в action. И даже с 1d-входом не так много преимуществ для выполнения вызова np.array во время разбора. Массирование (и тестирование) значений args после разбора является отличной практикой.

Было бы лучше, хотя бы поместить значения массива в файл CSV и указать имя этого файла через argparse. argparse действительно не предназначен для ввода большого количества значений. Это не парсер общего назначения. Командная строка управляет поведением вашего кода.

+0

Я имел в виду указать описание аргумента (тип, значение по умолчанию и все) при добавлении аргумента в ArgumentParser, как показано @Tadhg. – Tohiko