Требуется простой пример argparse: 1 аргумент, 3 результата

документация для модуля python argparse, хотя я уверен, что она превосходна, слишком велика, чтобы ее крошечный мозг новичка мог понять прямо сейчас. Мне не нужно делать математику в командной строке или вмешиваться в форматирование строк на экране или изменять параметры символов. Все, что я хочу сделать, это "Если arg - A, сделайте это, если B сделает это, если ни один из вышеперечисленных не показывает помощь и выход".

Ответ 1

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

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("a")
args = parser.parse_args()

if args.a == 'magic.name':
    print 'You nailed it!'

Но этот позиционный аргумент теперь требуется. Если вы оставите это при вызове этой программы, вы получите сообщение об ошибке. Это приводит меня ко второй части исходного вопроса. Кажется, что Matt Wilkie хочет один необязательный аргумент без именованного ярлыка (метки -option). Мое предложение состояло в том, чтобы изменить приведенный выше код следующим образом:

...
parser.add_argument("a", nargs='?', default="check_string_for_empty")
...
if args.a == 'check_string_for_empty':
    print 'I can tell that no argument was given and I can deal with that here.'
elif args.a == 'magic.name':
    print 'You nailed it!'
else:
    print args.a

Там может быть более элегантное решение, но это работает и минималистично.

Ответ 2

Вот как это сделать с помощью argparse (с несколькими аргументами):

parser = argparse.ArgumentParser(description='Description of your program')
parser.add_argument('-f','--foo', help='Description for foo argument', required=True)
parser.add_argument('-b','--bar', help='Description for bar argument', required=True)
args = vars(parser.parse_args())

args будет словарем, содержащим аргументы:

if args['foo'] == 'Hello':
    # code here

if args['bar'] == 'World':
    # code here

В вашем случае просто добавьте только один аргумент.

Ответ 3

Документация argparse достаточно хороша, но оставляет несколько полезных сведений, которые могут быть не очевидны. (@Diego Navarro уже упомянул об этом, но я попытаюсь немного расширить его ответ.) Основное использование выглядит следующим образом:

parser = argparse.ArgumentParser()
parser.add_argument('-f', '--my-foo', default='foobar')
parser.add_argument('-b', '--bar-value', default=3.14)
args = parser.parse_args()

Объект, возвращаемый с parse_args(), является объектом "Пространство имен": объект, чьи переменные-члены называются после аргументов командной строки. Объектом Namespace является доступ к вашим аргументам и связанным с ними значениям:

args = parser.parse_args()
print args.my_foo
print args.bar_value

(Обратите внимание, что argparse заменяет "-" в ваших именах аргументов символами подчеркивания при именах переменных.)

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

parser.add_argument('--foo', action='store_true')
parser.add_argument('--no-foo', action='store_false')

Вышеупомянутые будут создавать переменные с именем "foo" со значением True и "no_foo" со значением False соответственно:

if (args.foo):
    print "foo is true"

if (args.no_foo is False):
    print "nofoo is false"

Обратите внимание, что при добавлении аргумента вы можете использовать параметр "required":

parser.add_argument('-o', '--output', required=True)

Таким образом, если вы опустите этот аргумент в командной строке argparse, вы сообщите ему об этом и прекратите выполнение вашего script.

Наконец, обратите внимание, что возможно создать структуру аргументов ваших аргументов с помощью функции vars, если это облегчит вам жизнь.

args = parser.parse_args()
argsdict = vars(args)
print argsdict['my_foo']
print argsdict['bar_value']

Как вы можете видеть, vars возвращает dict с вашими именами аргументов в качестве ключей и их значениями как, er, значения.

Есть много других вариантов и вещей, которые вы можете сделать, но это должно охватывать наиболее важные и общие сценарии использования.

Ответ 4

Мэтт спрашивает о позиционных параметрах в argparse, и я согласен с тем, что документация на Python отсутствует в этом аспекте. Там нет ни одного, полного примера на ~ 20 нечетных страницах, которые показывают как синтаксический анализ, так и использование позиционных параметров.

Ни один из других ответов здесь не показывает полный пример позиционных параметров, так что вот полный пример:

# tested with python 2.7.1
import argparse

parser = argparse.ArgumentParser(description="An argparse example")

parser.add_argument('action', help='The action to take (e.g. install, remove, etc.)')
parser.add_argument('foo-bar', help='Hyphens are cumbersome in positional arguments')

args = parser.parse_args()

if args.action == "install":
    print("You asked for installation")
else:
    print("You asked for something other than installation")

# The following do not work:
# print(args.foo-bar)
# print(args.foo_bar)

# But this works:
print(getattr(args, 'foo-bar'))

То, что меня отбросило, это то, что argparse преобразует именованный аргумент "-foo-bar" в "foo_bar", но позиционный параметр с именем "foo-bar" остается "foo-bar", что делает его менее очевидно, как использовать его в вашей программе.

Обратите внимание на две строки в конце моего примера - ни один из них не будет работать, чтобы получить значение параметра foo-bar positional. Первый явно ошибочен (это арифметическое выражение args.foo минус bar), но второй тоже не работает:

AttributeError: 'Namespace' object has no attribute 'foo_bar'

Если вы хотите использовать атрибут foo-bar, вы должны использовать getattr, как показано в последней строке моего примера. Какое безумие в том, что если вы попытались использовать dest=foo_bar, чтобы изменить имя свойства на что-то более доступное, вы получите действительно странное сообщение об ошибке:

ValueError: dest supplied twice for positional argument

Вот пример выполнения приведенного выше примера:

$ python test.py
usage: test.py [-h] action foo-bar
test.py: error: too few arguments

$ python test.py -h
usage: test.py [-h] action foo-bar

An argparse example

positional arguments:
  action      The action to take (e.g. install, remove, etc.)
  foo-bar     Hyphens are cumbersome in positional arguments

optional arguments:
  -h, --help  show this help message and exit

$ python test.py install foo
You asked for installation
foo

Ответ 5

Еще одно краткое введение, вдохновленное этим постом.

import argparse

# define functions, classes, etc.

# executes when your script is called from the command-line
if __name__ == "__main__":

    parser = argparse.ArgumentParser()
    #
    # define each option with: parser.add_argument
    #
    args = parser.parse_args() # automatically looks at sys.argv
    #
    # access results with: args.argumentName
    #

Аргументы определяются с помощью следующих комбинаций:

parser.add_argument( 'name', options... )              # positional argument
parser.add_argument( '-x', options... )                # single-char flag
parser.add_argument( '-x', '--long-name', options... ) # flag with long name

Общие параметры:

  • help: описание этого аргумента при использовании --help.
  • default: значение по умолчанию, если аргумент опущен.
  • введите: если вы ожидаете float или int (в противном случае это str).
  • dest: присвоить флагу другое имя (например, '-x', '--long-name', dest='longName').
    Примечание: по умолчанию доступ к --long-name осуществляется с помощью args.long_name
  • действие: для специальной обработки определенных аргументов
    • store_true, store_false: для логических аргументов
      '--foo', action='store_true' => args.foo == True
    • store_const: для использования с опцией const
      '--foo', action='store_const', const=42 => args.foo == 42
    • count: для повторяющихся опций, как в ./myscript.py -vv
      '-v', action='count' => args.v == 2
    • append: для повторяющихся опций, как в ./myscript.py --foo 1 --foo 2
      '--foo', action='append' => args.foo == ['1', '2']
  • обязательно: если требуется флаг или позиционный аргумент - нет.
  • nargs: чтобы флаг захватывал N аргументов
    ./myscript.py --foo a b => args.foo = ['a', 'b']
  • выбор: ограничить возможные входные данные (указать в виде списка строк или целых, если type=int).

Ответ 6

Обратите внимание на Руководство по Argparse в POWON HOWTO. Он начинается с большинства базовых примеров, таких как:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
                    help="display a square of a given number")
args = parser.parse_args()
print(args.square**2)

и переходит к менее базовым.

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

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
                    help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2],
                    help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
    print("the square of {} equals {}".format(args.square, answer))
elif args.verbosity == 1:
    print("{}^2 == {}".format(args.square, answer))
else:
    print(answer)

Ответ 7

Вот что я придумал в своем учебном проекте, в основном благодаря @DMH...

Демо-код:

import argparse

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-f', '--flag', action='store_true', default=False)  # can 'store_false' for no-xxx flags
    parser.add_argument('-r', '--reqd', required=True)
    parser.add_argument('-o', '--opt', default='fallback')
    parser.add_argument('arg', nargs='*') # use '+' for 1 or more args (instead of 0 or more)
    parsed = parser.parse_args()
    # NOTE: args with '-' have it replaced with '_'
    print('Result:',  vars(parsed))
    print('parsed.reqd:', parsed.reqd)

if __name__ == "__main__":
    main()

Это может развиться и доступно онлайн: command-line.py

Script, чтобы дать этому коду тренировку: command-line-demo.sh

Ответ 8

Чтобы добавить к словам других:

Мне обычно нравится использовать параметр "dest", чтобы указать имя переменной, а затем использовать "globals(). update()", чтобы поместить эти переменные в глобальное пространство имен.

Использование:

$ python script.py -i "Hello, World!"

код:

...
parser.add_argument('-i', '--input', ..., dest='inputted_variable',...)
globals().update(vars(parser.parse_args()))
...
print(inputted_variable) # Prints "Hello, World!"

Ответ 9

Вы также можете использовать plac (обертка вокруг argparse).

В качестве бонуса он генерирует аккуратные инструкции по оказанию помощи - см. ниже.

Пример script:

#!/usr/bin/env python3
def main(
    arg: ('Argument with two possible values', 'positional', None, None, ['A', 'B'])
):
    """General help for application"""
    if arg == 'A':
        print("Argument has value A")
    elif arg == 'B':
        print("Argument has value B")

if __name__ == '__main__':
    import plac
    plac.call(main)

Пример вывода:

Нет аргументов - example.py:

usage: example.py [-h] {A,B}
example.py: error: the following arguments are required: arg

Непредвиденный аргумент - example.py C:

usage: example.py [-h] {A,B}
example.py: error: argument arg: invalid choice: 'C' (choose from 'A', 'B')

Правильный аргумент - example.py A:

Argument has value A

Полное меню помощи (сгенерировано автоматически) - example.py -h:

usage: example.py [-h] {A,B}

General help for application

positional arguments:
  {A,B}       Argument with two possible values

optional arguments:
  -h, --help  show this help message and exit

Краткое объяснение:

Имя аргумента обычно равно имени параметра (arg).

Аннотации кортежа после параметра arg имеют следующее значение:

  • Описание (Argument with two possible values)
  • Тип аргумента - один из "флаг", "опция" или "позиционный" (positional)
  • Аббревиатура (None)
  • Тип значения аргумента - например. float, string (None)
  • Ограниченный набор вариантов (['A', 'B'])

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

Чтобы узнать больше об использовании plac, ознакомьтесь с его замечательной документацией:

Plac: Разбор командной строки - простой способ

Ответ 10

Действительно простой способ использования argparse и изменения переключателей '-h'/'- -h elp' для отображения ваших собственных справочных инструкций кода состоит в том, чтобы задать для справки по умолчанию значение False, вы также можете добавить столько дополнительных .add_arguments как вам нравится:

import argparse

parser = argparse.ArgumentParser(add_help=False)

parser.add_argument('-h', '--help', action='help',
                help='To run this script please provide two arguments')
parser.parse_args()

Выполнить: python test.py -h

Выход:

usage: test.py [-h]

optional arguments:
  -h, --help  To run this script please provide two arguments