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



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

515   9  

9 ответов:

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

import argparse

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

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

но этот позиционный аргумент теперь является обязательным. Если вы оставите его при вызове этой программы, вы получите ошибку об отсутствии аргументов. Это приводит меня ко второй части первоначального вопроса. Матовый Уилки, кажется, хочет один дополнительно аргумент без именованной метки (метки --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

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

вот как я это делаю с 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

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

The 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"

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

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

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

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

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

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

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

Мэтт спрашивает о позиционных параметрах в 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. Первый явно ошибочен (это арифметическое выражение args.foo минус бар), но второй тоже не работает:

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

Примечание Argparse Tutorial на Python HOWTOs. Он начинается с самых простых примеров, таких как этот:

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)

вот что я придумал в своем учебном проекте в основном благодаря @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

скрипт для тренировки этого кода:command-line-demo.sh

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

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

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

  • помогите: описание для этого arg когда есть.
  • по умолчанию: значение по умолчанию, если аргумент опущен.
  • тип: если вы ожидаете 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']
  • выбор: чтобы ограничить возможные входы (укажите как список строк или ints, если type=int).

добавить к тому, что сказали другие:

обычно я использую параметр '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!"

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

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

пример:

#!/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: разбор командной строки простой способ

Comments

    Ничего не найдено.