аргумент аргумента argparse

У меня небольшая проблема.

Я использую argparse для анализа моих аргументов, и он работает очень хорошо.

Чтобы иметь аргументы, я делаю:

 p_args = parser.parse_args(argv) args = dict(p_args._get_kwargs()) 

Но проблема с p_args заключается в том, что я не знаю, как получить эти аргументы, упорядоченные по их позиции в командной строке, потому что это dict.

Итак, есть ли возможность иметь аргументы в кортеже / списке / упорядоченном dict своим порядком в командной строке?

5 Solutions collect form web for “аргумент аргумента argparse”

Чтобы сохранить упорядоченные аргументы, я использую настраиваемое действие следующим образом:

 import argparse class CustomAction(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): if not 'ordered_args' in namespace: setattr(namespace, 'ordered_args', []) previous = namespace.ordered_args previous.append((self.dest, values)) setattr(namespace, 'ordered_args', previous) parser = argparse.ArgumentParser() parser.add_argument('--test1', action=CustomAction) parser.add_argument('--test2', action=CustomAction) 

Чтобы использовать его, например:

 >>> parser.parse_args(['--test2', '2', '--test1', '1']) Namespace(ordered_args=[('test2', '2'), ('test1', '1')], test1=None, test2=None) 

Если вам нужно знать порядок, в котором аргументы отображаются в вашем синтаксическом анализаторе, вы можете настроить парсер следующим образом:

 import argparse parser = argparse.ArgumentParser(description = "A cool application.") parser.add_argument('--optional1') parser.add_argument('positionals', nargs='+') parser.add_argument('--optional2') args = parser.parse_args() print args.positionals 

Вот краткий пример запуска этого кода:

 $ python s.py --optional1 X --optional2 Y 1 2 3 4 5 ['1', '2', '3', '4', '5'] 

Обратите внимание, что args.positionals – это список с позиционными аргументами в порядке. Дополнительную информацию см. В документации по argparse .

Это немного хрупко, поскольку он полагается на понимание внутренних элементов argparse.ArgumentParser, но вместо перезаписи argparse.ArgumentParser.parse_known_args, вот что я использую:

 class OrderedNamespace(argparse.Namespace): def __init__(self, **kwargs): self.__dict__["_arg_order"] = [] self.__dict__["_arg_order_first_time_through"] = True argparse.Namespace.__init__(self, **kwargs) def __setattr__(self, name, value): #print("Setting %s -> %s" % (name, value)) self.__dict__[name] = value if name in self._arg_order and hasattr(self, "_arg_order_first_time_through"): self.__dict__["_arg_order"] = [] delattr(self, "_arg_order_first_time_through") self.__dict__["_arg_order"].append(name) def _finalize(self): if hasattr(self, "_arg_order_first_time_through"): self.__dict__["_arg_order"] = [] delattr(self, "_arg_order_first_time_through") def _latest_of(self, k1, k2): try: print self._arg_order if self._arg_order.index(k1) > self._arg_order.index(k2): return k1 except ValueError: if k1 in self._arg_order: return k1 return k2 

Это работает благодаря знанию, что argparse.ArgumentParser.parse_known_args проходит через весь список опций после установки значений по умолчанию для каждого аргумента. Это означает, что указанные пользователем аргументы начинаются с первого раза, когда setattr показывает аргумент, который он видел раньше.

Применение:

 options, extra_args = parser.parse_known_args(sys.argv, namespace=OrderedNamespace()) 

Вы можете проверить options._arg_order для порядка пользовательских аргументов командной строки или использовать options._latest_of("arg1", "arg2") чтобы узнать, какой из -arg1 или -arg2 был указан позже в командной строке (который , для моих целей было то, что мне нужно: видя, какой из двух вариантов был бы первостепенным).

UPDATE: пришлось добавить метод _finalize для обработки патологического случая sys.argv (), не содержащего никаких аргументов в списке)

Для этого специально разработан модуль:

https://github.com/claylabs/ordered-keyword-args

без использования модуля orderkwargs

 def multiple_kwarguments(first , **lotsofothers): print first for i,other in lotsofothers: print other return True multiple_kwarguments("first", second="second", third="third" ,fourth="fourth" ,fifth="fifth") 

вывод:

 first second fifth fourth third 

При использовании упорядоченного модуля

 from orderedkwargs import ordered kwargs @orderedkwargs def mutliple_kwarguments(first , *lotsofothers): print first for i, other in lotsofothers: print other return True mutliple_kwarguments("first", second="second", third="third" ,fourth="fourth" ,fifth="fifth") 

Вывод:

 first second third fourth fifth 

Примечание. При использовании этого модуля с декоратором над функцией требуется одиночный астерик.

Мне это нужно, потому что для ведения журналов мне нравилось печатать аргументы после их анализа. Проблема состояла в том, что аргументы не были напечатаны по порядку, что было очень неприятно.

Пользовательский класс действий просто плоский не работал для меня. У меня были другие аргументы, которые использовали другое действие, такое как 'store_true' и аргументы по default также не работают, поскольку пользовательский класс действия не вызывается, если аргумент не указан в командной строке. Что для меня работало, так это создание класса-оболочки:

 import collections from argparse import ArgumentParser class SortedArgumentParser(): def __init__(self, *args, **kwargs): self.ap = ArgumentParser(*args, **kwargs) self.args_dict = collections.OrderedDict() def add_argument(self, *args, **kwargs): self.ap.add_argument(*args, **kwargs) # Also store dest kwarg self.args_dict[kwargs['dest']] = None def parse_args(self): # Returns a sorted dictionary unsorted_dict = self.ap.parse_args().__dict__ for unsorted_entry in unsorted_dict: self.args_dict[unsorted_entry] = unsorted_dict[unsorted_entry] return self.args_dict 

add_argument метод add_argument должен иметь ту же функциональность, что и оригинальный ArgumentParser . Недостатки заключаются в том, что если вам нужны другие методы, вам придется написать их для всех. К счастью для меня все, что я когда-либо использовал, это add_argument и parse_args , так что это послужило моим целям довольно хорошо. Вам также нужно будет сделать больше работы, если вы хотите использовать родительские ArgumentParser .

  • Сделать namedtuple принимать kwargs
  • Pass!,! =, ~, <,> Как параметры
  • Вложенные декораторы функций, которые работают с аргументами в python
  • Python Multiprocessing - Как передать функции kwargs?
  • Использование argparse с функцией, которая принимает аргумент ** kwargs
  • Четко передайте позиционные аргументы как аргументы и необязательные аргументы как kwargs от argpase к функции
  • Получить внутреннюю функцию kwargs
  • kwargs в исполняемых файлах python
  •  
    Interesting Posts for Van-Lav

    Как использовать vi-ключи в ipython под * nix?

    Итерация через искровой RDD

    Отсутствует Python.h при попытке скомпилировать модуль расширения C

    Как программно подсчитать количество файлов в архиве с помощью python

    python matplotlib framework под macosx?

    Как преобразовать кортеж в строку в Python?

    'getattr (): имя атрибута должно быть строкой' error в панели администратора для модели с ImageField

    Предотвращение django из добавления «_id» в поле внешнего ключа

    Как импортировать файл python, расположенный в том же подкаталоге в проекте pycharm

    BeautifulSoup findAll () для нескольких классов?

    Python: получить указатель на элемент списка

    Предварительная обработка Sklearn – PolynomialFeatures – Как сохранить имена столбцов / заголовки выходного массива / dataframe

    Есть ли более pythonic способ открыть файл, если он указан как аргумент или stdin, если нет?

    TypeError: __init __ () отсутствует 2 необходимых позиционных аргумента: 'client_socket' и 'statusMessage'

    Захват одного изображения с моей веб-камеры в Java или Python

    Python - лучший язык программирования в мире.