Использование argparse для разбора аргументов вида "arg = val" - PullRequest
17 голосов
/ 01 марта 2011

Я хочу использовать argparse для разбора командных строк в форме "arg = val". Например, использование будет:

script.py conf_dir=/tmp/good_conf

Чтобы достичь этого, я делаю это:

desc   = "details"
parser = argparse.ArgumentParser(description=desc, add_help=False)
args = parser.add_argument("conf_dir")
args = parser.parse_args("conf_dir=FOO".split())
args = parser.parse_args()
print args.conf_dir

Но проблема в том, что при вызове сценария с:

python script.py conf_dir=/tmp/good_conf

я получаю:

conf_dir=/tmp/good_conf

Где, как я ожидаю

/tmp/good_conf

Итак, вопрос: могу ли я использовать argparse для разбора строки cmd, которая содержит пары имя-значение?Любые советы?

Редактировать: причина, по которой я хочу сделать это, а не что-то вроде --conf_dir = / tmp / good_dir, заключается в том, что есть другие инструменты (написанные на другом языке), которые используют conf_dir = / tmp/ good_dir стиль аргументов.Чтобы сохранить последовательность, я должен был разобрать аргументы таким образом.

Ответы [ 4 ]

25 голосов
/ 01 августа 2012

Вам нужно пользовательское действие

class StoreNameValuePair(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        n, v = values.split('=')
        setattr(namespace, n, v)

args = parser.add_argument("conf_dir", action=StoreNameValuePair)
5 голосов
/ 01 марта 2011

Согласно документация , argparse изначально не позволяет использовать такие опции без префикса.Если вы опускаете ведущий -, он предполагает, что вы описываете позиционный аргумент, и ожидает, что он будет представлен как:

python script.py /tmp/good_conf

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

python script.py --conf_dir=/tmp/good_conf

Однако, чтобы принять пары имя-значение, вы можете реализовать пользовательское действие .В сочетании с nargs такое действие может принять произвольное количество пар имя-значение и сохранить их в объекте результата анализа аргумента.

1 голос
/ 13 ноября 2018

@ chepner Это здорово.Я улучшил это, чтобы также поддерживать несколько аргументов и сохранять результат как dict:

class StoreDict(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        kv={}
        if not isinstance(values, (list,)):
            values=(values,)
        for value in values:
            n, v = value.split('=')
            kv[n]=v
        setattr(namespace, self.dest, kv)
1 голос
/ 01 марта 2011

Обычный способ поместить пары имя-значение в командную строку - с помощью параметров.Т.е. вы бы использовали

python script.py --confdir=/tmp/good_conf

argparse, безусловно, может обработать этот случай.См. Документы по адресу:

http://docs.python.org/library/argparse.html#option-value-syntax

...