# Підручник Argparse

автор:

  Tshepang Mbambo

Цей підручник призначений для ознайомлення з `argparse`, рекомендованим модулем аналізу командного рядка в стандартній бібліотеці Python.

Примітка

The standard library includes two other libraries directly related to command-line parameter processing: the lower level `optparse` module (which may require more code to configure for a given application, but also allows an application to request behaviors that `argparse` doesn’t support), and the very low level `getopt` (which specifically serves as an equivalent to the `getopt()` family of functions available to C programmers). While neither of those modules is covered directly in this guide, many of the core concepts in `argparse` first originated in `optparse`, so some aspects of this tutorial will also be relevant to `optparse` users.

## Концепції

Давайте покажемо тип функціональності, який ми збираємося досліджувати в цьому вступному посібнику, використовуючи команду ls:

    $ ls
    cpython  devguide  prog.py  pypy  rm-unused-function.patch
    $ ls pypy
    ctypes_configure  demo  dotviewer  include  lib_pypy  lib-python ...
    $ ls -l
    total 20
    drwxr-xr-x 19 wena wena 4096 Feb 18 18:51 cpython
    drwxr-xr-x  4 wena wena 4096 Feb  8 12:04 devguide
    -rwxr-xr-x  1 wena wena  535 Feb 19 00:05 prog.py
    drwxr-xr-x 14 wena wena 4096 Feb  7 00:59 pypy
    -rw-r--r--  1 wena wena  741 Feb 18 01:01 rm-unused-function.patch
    $ ls --help
    Usage: ls [OPTION]... [FILE]...
    List information about the FILEs (the current directory by default).
    Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.
    ...

Кілька понять, які ми можемо вивчити з чотирьох команд:

- Команда ls корисна, якщо її запускати без жодних опцій. За замовчуванням відображається вміст поточного каталогу.

- Якщо ми хочемо вийти за межі того, що він надає за замовчуванням, ми розповідаємо про це трохи більше. У цьому випадку ми хочемо, щоб він відображав інший каталог, `pypy`. Ми вказали так званий позиційний аргумент. Це названо так, тому що програма повинна знати, що робити зі значенням, виключно на основі того, де воно з’являється в командному рядку. Ця концепція більш актуальна для такої команди, як cp, основним використанням якої є `cp SRC DEST`. Перша позиція — це те, що ви хочете скопіювати, а друга позиція — це куди ви хочете це скопіювати.

- Тепер, скажімо, ми хочемо змінити поведінку програми. У нашому прикладі ми показуємо більше інформації для кожного файлу, а не просто показуємо імена файлів. `-l` у цьому випадку відомий як необов’язковий аргумент.

- Це фрагмент довідкового тексту. Це дуже корисно, оскільки ви можете натрапити на програму, якою ніколи раніше не користувалися, і зрозуміти, як вона працює, просто прочитавши довідковий текст.

## Основи

Почнемо з дуже простого прикладу, який (майже) нічого не робить:

    import argparse
    parser = argparse.ArgumentParser()
    parser.parse_args()

Нижче наведено результат виконання коду:

    $ python prog.py
    $ python prog.py --help
    usage: prog.py [-h]

    options:
      -h, --help  show this help message and exit
    $ python prog.py --verbose
    usage: prog.py [-h]
    prog.py: error: unrecognized arguments: --verbose
    $ python prog.py foo
    usage: prog.py [-h]
    prog.py: error: unrecognized arguments: foo

Ось що відбувається:

- Запуск сценарію без будь-яких параметрів призводить до того, що стандартний вивід нічого не відображає. Не дуже корисно.

- Другий починає відображати корисність модуля `argparse`. Ми майже нічого не зробили, але вже отримуємо гарне довідкове повідомлення.

- Опція `--help`, яку також можна скоротити до `-h`, є єдиною опцією, яку ми отримуємо безкоштовно (тобто її не потрібно вказувати). Вказівка будь-чого іншого призводить до помилки. Але навіть тоді ми отримуємо корисне повідомлення про використання, також безкоштовно.

## Представлення позиційних аргументів

Приклад:

    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("echo")
    args = parser.parse_args()
    print(args.echo)

І запуск коду:

    $ python prog.py
    usage: prog.py [-h] echo
    prog.py: error: the following arguments are required: echo
    $ python prog.py --help
    usage: prog.py [-h] echo

    positional arguments:
      echo

    options:
      -h, --help  show this help message and exit
    $ python prog.py foo
    foo

Ось що відбувається:

- We’ve added the `add_argument()` method, which is what we use to specify which command-line options the program is willing to accept. In this case, I’ve named it `echo` so that it’s in line with its function.

- Для виклику нашої програми тепер потрібно вказати опцію.

- The `parse_args()` method actually returns some data from the options specified, in this case, `echo`.

- Змінна є певною формою «магії», яку `argparse` виконує безкоштовно (тобто не потрібно вказувати, у якій змінній це значення зберігається). Ви також помітите, що його назва відповідає рядковому аргументу, наданому методу, `echo`.

Зауважте, однак, що, незважаючи на те, що екран довідки виглядає гарно і все таке, наразі він не такий корисний, як міг би бути. Наприклад, ми бачимо, що ми отримали `echo` як позиційний аргумент, але ми не знаємо, що він робить, окрім здогадок або читання вихідного коду. Отже, давайте зробимо це трохи кориснішим:

    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("echo", help="echo the string you use here")
    args = parser.parse_args()
    print(args.echo)

І отримуємо:

    $ python prog.py -h
    usage: prog.py [-h] echo

    positional arguments:
      echo        echo the string you use here

    options:
      -h, --help  show this help message and exit

А тепер як щодо того, щоб зробити щось ще корисніше:

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

Нижче наведено результат виконання коду:

    $ python prog.py 4
    Traceback (most recent call last):
      File "prog.py", line 5, in <module>
        print(args.square**2)
    TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'

Це пішло не так добре. Це тому, що `argparse` розглядає надані нами параметри як рядки, якщо ми не вкажемо інше. Отже, давайте скажемо `argparse` розглядати цей вхід як ціле число:

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

Нижче наведено результат виконання коду:

    $ python prog.py 4
    16
    $ python prog.py four
    usage: prog.py [-h] square
    prog.py: error: argument square: invalid int value: 'four'

Це пройшло добре. Програма тепер навіть допомагає завершити роботу, якщо неправильно введено неправильні дані, перш ніж продовжити.

## Представляємо додаткові аргументи

Досі ми гралися з позиційними аргументами. Давайте розглянемо, як додати необов’язкові:

    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("--verbosity", help="increase output verbosity")
    args = parser.parse_args()
    if args.verbosity:
        print("verbosity turned on")

І вихід:

    $ python prog.py --verbosity 1
    verbosity turned on
    $ python prog.py
    $ python prog.py --help
    usage: prog.py [-h] [--verbosity VERBOSITY]

    options:
      -h, --help            show this help message and exit
      --verbosity VERBOSITY
                            increase output verbosity
    $ python prog.py --verbosity
    usage: prog.py [-h] [--verbosity VERBOSITY]
    prog.py: error: argument --verbosity: expected one argument

Ось що відбувається:

- Програма написана таким чином, щоб щось відображати, коли вказано `--verbosity`, і нічого не відображати, якщо ні.

- To show that the option is actually optional, there is no error when running the program without it. Note that by default, if an optional argument isn’t used, the relevant variable, in this case `args.verbosity`, is given `None` as a value, which is the reason it fails the truth test of the `if` statement.

- Довідкове повідомлення дещо інше.

- При використанні опції `--verbosity` необхідно також вказати певне значення, будь-яке значення.

Наведений вище приклад приймає довільні цілі значення для `--verbosity`, але для нашої простої програми насправді корисними є лише два значення, `True` або `False`. Давайте відповідно змінимо код:

    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("--verbose", help="increase output verbosity",
                        action="store_true")
    args = parser.parse_args()
    if args.verbose:
        print("verbosity turned on")

І вихід:

    $ python prog.py --verbose
    verbosity turned on
    $ python prog.py --verbose 1
    usage: prog.py [-h] [--verbose]
    prog.py: error: unrecognized arguments: 1
    $ python prog.py --help
    usage: prog.py [-h] [--verbose]

    options:
      -h, --help  show this help message and exit
      --verbose   increase output verbosity

Ось що відбувається:

- The option is now more of a flag than something that requires a value. We even changed the name of the option to match that idea. Note that we now specify a new keyword, `action`, and give it the value `"store_true"`. This means that, if the option is specified, assign the value `True` to `args.verbose`. Not specifying it implies `False`.

- Він скаржиться, коли ви вказуєте значення, у справжньому дусі того, чим насправді є прапори.

- Зверніть увагу на інший текст довідки.

### Короткі варіанти

Якщо ви знайомі з використанням командного рядка, ви помітите, що я ще не торкався теми коротких версій параметрів. Це досить просто:

    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("-v", "--verbose", help="increase output verbosity",
                        action="store_true")
    args = parser.parse_args()
    if args.verbose:
        print("verbosity turned on")

І ось:

    $ python prog.py -v
    verbosity turned on
    $ python prog.py --help
    usage: prog.py [-h] [-v]

    options:
      -h, --help     show this help message and exit
      -v, --verbose  increase output verbosity

Зверніть увагу, що нова здатність також відображається в тексті довідки.

## Поєднання позиційних і необов’язкових аргументів

Наша програма постійно ускладнюється:

    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("square", type=int,
                        help="display a square of a given number")
    parser.add_argument("-v", "--verbose", action="store_true",
                        help="increase output verbosity")
    args = parser.parse_args()
    answer = args.square**2
    if args.verbose:
        print(f"the square of {args.square} equals {answer}")
    else:
        print(answer)

А тепер вихід:

    $ python prog.py
    usage: prog.py [-h] [-v] square
    prog.py: error: the following arguments are required: square
    $ python prog.py 4
    16
    $ python prog.py 4 --verbose
    the square of 4 equals 16
    $ python prog.py --verbose 4
    the square of 4 equals 16

- Ми повернули позиційний аргумент, тому скарга.

- Зауважте, що порядок не має значення.

Як щодо того, щоб ми повернули цій нашій програмі можливість мати кілька значень докладності та фактично отримати їх використання:

    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,
                        help="increase output verbosity")
    args = parser.parse_args()
    answer = args.square**2
    if args.verbosity == 2:
        print(f"the square of {args.square} equals {answer}")
    elif args.verbosity == 1:
        print(f"{args.square}^2 == {answer}")
    else:
        print(answer)

І вихід:

    $ python prog.py 4
    16
    $ python prog.py 4 -v
    usage: prog.py [-h] [-v VERBOSITY] square
    prog.py: error: argument -v/--verbosity: expected one argument
    $ python prog.py 4 -v 1
    4^2 == 16
    $ python prog.py 4 -v 2
    the square of 4 equals 16
    $ python prog.py 4 -v 3
    16

Усі вони виглядають добре, крім останнього, який виявляє помилку в нашій програмі. Давайте виправимо це, обмеживши значення, які може приймати параметр `--verbosity`:

    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(f"the square of {args.square} equals {answer}")
    elif args.verbosity == 1:
        print(f"{args.square}^2 == {answer}")
    else:
        print(answer)

І вихід:

    $ python prog.py 4 -v 3
    usage: prog.py [-h] [-v {0,1,2}] square
    prog.py: error: argument -v/--verbosity: invalid choice: 3 (choose from 0, 1, 2)
    $ python prog.py 4 -h
    usage: prog.py [-h] [-v {0,1,2}] square

    positional arguments:
      square                display a square of a given number

    options:
      -h, --help            show this help message and exit
      -v, --verbosity {0,1,2}
                            increase output verbosity

Зауважте, що зміна також відображається як у повідомленні про помилку, так і в рядку довідки.

Тепер давайте використаємо інший підхід гри з багатослівністю, який є досить поширеним. Це також відповідає тому, як виконуваний файл CPython обробляє власний аргумент багатослівності (перевірте вихід `python --help`):

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

Ми запровадили ще одну дію, «підрахунок», щоб підрахувати кількість повторень певних параметрів.

    $ python prog.py 4
    16
    $ python prog.py 4 -v
    4^2 == 16
    $ python prog.py 4 -vv
    the square of 4 equals 16
    $ python prog.py 4 --verbosity --verbosity
    the square of 4 equals 16
    $ python prog.py 4 -v 1
    usage: prog.py [-h] [-v] square
    prog.py: error: unrecognized arguments: 1
    $ python prog.py 4 -h
    usage: prog.py [-h] [-v] square

    positional arguments:
      square           display a square of a given number

    options:
      -h, --help       show this help message and exit
      -v, --verbosity  increase output verbosity
    $ python prog.py 4 -vvv
    16

- Так, тепер це більше позначка (схожа на `action="store_true"`) у попередній версії нашого сценарію. Це має пояснити скаргу.

- Він також поводиться подібно до дії «store_true».

- Тепер ось демонстрація того, що дає дія «підрахунок». Ви, напевно, бачили таке використання раніше.

- І якщо ви не вкажете прапорець `-v`, цей прапорець вважатиметься таким, що має значення `None`.

- Як і слід було очікувати, вказавши довгу форму прапора, ми повинні отримати той самий результат.

- На жаль, результати нашої довідки не надто інформативні щодо нових можливостей, які отримав наш сценарій, але це завжди можна виправити, покращивши документацію для нашого сценарію (наприклад, за допомогою аргументу ключового слова `help`).

- Цей останній вихід виявляє помилку в нашій програмі.

Виправимо:

    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("square", type=int,
                        help="display a square of a given number")
    parser.add_argument("-v", "--verbosity", action="count",
                        help="increase output verbosity")
    args = parser.parse_args()
    answer = args.square**2

    # bugfix: replace == with >=
    if args.verbosity >= 2:
        print(f"the square of {args.square} equals {answer}")
    elif args.verbosity >= 1:
        print(f"{args.square}^2 == {answer}")
    else:
        print(answer)

І ось що це дає:

    $ python prog.py 4 -vvv
    the square of 4 equals 16
    $ python prog.py 4 -vvvv
    the square of 4 equals 16
    $ python prog.py 4
    Traceback (most recent call last):
      File "prog.py", line 11, in <module>
        if args.verbosity >= 2:
    TypeError: '>=' not supported between instances of 'NoneType' and 'int'

- Перший вихід пройшов добре та виправляє помилку, яку ми мали раніше. Тобто ми хочемо, щоб будь-яке значення >= 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", action="count", default=0,
                        help="increase output verbosity")
    args = parser.parse_args()
    answer = args.square**2
    if args.verbosity >= 2:
        print(f"the square of {args.square} equals {answer}")
    elif args.verbosity >= 1:
        print(f"{args.square}^2 == {answer}")
    else:
        print(answer)

Ми щойно представили ще одне ключове слово, `default`. Ми встановили для нього значення `0`, щоб зробити його порівнянним з іншими значеннями int. Пам’ятайте, що за замовчуванням, якщо необов’язковий аргумент не вказано, він отримує значення `None`, яке не можна порівняти зі значенням int (отже, виняток `TypeError`).

і:

    $ python prog.py 4
    16

Ви можете зайти досить далеко лише з тим, що ми навчилися досі, і ми лише подряпали поверхню. Модуль `argparse` дуже потужний, і ми вивчимо його трохи більше, перш ніж закінчити цей підручник.

## Ставши трохи більш просунутим

Що, якби ми захотіли розширити нашу крихітну програму для виконання інших ступенів, а не лише квадратів:

    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("x", type=int, help="the base")
    parser.add_argument("y", type=int, help="the exponent")
    parser.add_argument("-v", "--verbosity", action="count", default=0)
    args = parser.parse_args()
    answer = args.x**args.y
    if args.verbosity >= 2:
        print(f"{args.x} to the power {args.y} equals {answer}")
    elif args.verbosity >= 1:
        print(f"{args.x}^{args.y} == {answer}")
    else:
        print(answer)

Вихід:

    $ python prog.py
    usage: prog.py [-h] [-v] x y
    prog.py: error: the following arguments are required: x, y
    $ python prog.py -h
    usage: prog.py [-h] [-v] x y

    positional arguments:
      x                the base
      y                the exponent

    options:
      -h, --help       show this help message and exit
      -v, --verbosity
    $ python prog.py 4 2 -v
    4^2 == 16

Зверніть увагу, що досі ми використовували рівень докладності, щоб змінити текст, який відображається. Натомість у наступному прикладі використовується рівень детальності для відображення більше тексту:

    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("x", type=int, help="the base")
    parser.add_argument("y", type=int, help="the exponent")
    parser.add_argument("-v", "--verbosity", action="count", default=0)
    args = parser.parse_args()
    answer = args.x**args.y
    if args.verbosity >= 2:
        print(f"Running '{__file__}'")
    if args.verbosity >= 1:
        print(f"{args.x}^{args.y} == ", end="")
    print(answer)

Вихід:

    $ python prog.py 4 2
    16
    $ python prog.py 4 2 -v
    4^2 == 16
    $ python prog.py 4 2 -vv
    Running 'prog.py'
    4^2 == 16

### Specifying ambiguous arguments

When there is ambiguity in deciding whether an argument is positional or for an argument, `--` can be used to tell `parse_args()` that everything after that is a positional argument:

    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('-n', nargs='+')
    >>> parser.add_argument('args', nargs='*')

    >>> # ambiguous, so parse_args assumes it's an option
    >>> parser.parse_args(['-f'])
    usage: PROG [-h] [-n N [N ...]] [args ...]
    PROG: error: unrecognized arguments: -f

    >>> parser.parse_args(['--', '-f'])
    Namespace(args=['-f'], n=None)

    >>> # ambiguous, so the -n option greedily accepts arguments
    >>> parser.parse_args(['-n', '1', '2', '3'])
    Namespace(args=[], n=['1', '2', '3'])

    >>> parser.parse_args(['-n', '1', '--', '2', '3'])
    Namespace(args=['2', '3'], n=['1'])

### Конфліктні варіанти

So far, we have been working with two methods of an `argparse.ArgumentParser` instance. Let’s introduce a third one, `add_mutually_exclusive_group()`. It allows for us to specify options that conflict with each other. Let’s also change the rest of the program so that the new functionality makes more sense: we’ll introduce the `--quiet` option, which will be the opposite of the `--verbose` one:

    import argparse

    parser = argparse.ArgumentParser()
    group = parser.add_mutually_exclusive_group()
    group.add_argument("-v", "--verbose", action="store_true")
    group.add_argument("-q", "--quiet", action="store_true")
    parser.add_argument("x", type=int, help="the base")
    parser.add_argument("y", type=int, help="the exponent")
    args = parser.parse_args()
    answer = args.x**args.y

    if args.quiet:
        print(answer)
    elif args.verbose:
        print(f"{args.x} to the power {args.y} equals {answer}")
    else:
        print(f"{args.x}^{args.y} == {answer}")

Наша програма стала простішою, і ми втратили деякі функції заради демонстрації. У будь-якому випадку, ось результат:

    $ python prog.py 4 2
    4^2 == 16
    $ python prog.py 4 2 -q
    16
    $ python prog.py 4 2 -v
    4 to the power 2 equals 16
    $ python prog.py 4 2 -vq
    usage: prog.py [-h] [-v | -q] x y
    prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose
    $ python prog.py 4 2 -v --quiet
    usage: prog.py [-h] [-v | -q] x y
    prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose

Це повинно бути легко слідкувати. Я додав цей останній вихід, щоб ви могли бачити, яку гнучкість ви отримуєте, тобто змішування параметрів довгої форми з опціями короткої.

Перш ніж завершити, ви, ймовірно, захочете повідомити своїм користувачам головну мету вашої програми, на випадок, якщо вони не знають:

    import argparse

    parser = argparse.ArgumentParser(description="calculate X to the power of Y")
    group = parser.add_mutually_exclusive_group()
    group.add_argument("-v", "--verbose", action="store_true")
    group.add_argument("-q", "--quiet", action="store_true")
    parser.add_argument("x", type=int, help="the base")
    parser.add_argument("y", type=int, help="the exponent")
    args = parser.parse_args()
    answer = args.x**args.y

    if args.quiet:
        print(answer)
    elif args.verbose:
        print(f"{args.x} to the power {args.y} equals {answer}")
    else:
        print(f"{args.x}^{args.y} == {answer}")

Зверніть увагу на невелику різницю в тексті використання. Зверніть увагу на `[-v | -q]`, який говорить нам, що ми можемо використовувати `-v` або `-q`, але не обидва одночасно:

    $ python prog.py --help
    usage: prog.py [-h] [-v | -q] x y

    calculate X to the power of Y

    positional arguments:
      x              the base
      y              the exponent

    options:
      -h, --help     show this help message and exit
      -v, --verbose
      -q, --quiet

## How to translate the argparse output

The output of the `argparse` module such as its help text and error messages are all made translatable using the `gettext` module. This allows applications to easily localize messages produced by `argparse`. See also Інтернаціоналізація ваших програм і модулів.

For instance, in this `argparse` output:

    $ python prog.py --help
    usage: prog.py [-h] [-v | -q] x y

    calculate X to the power of Y

    positional arguments:
      x              the base
      y              the exponent

    options:
      -h, --help     show this help message and exit
      -v, --verbose
      -q, --quiet

The strings `usage:`, `positional arguments:`, `options:` and `show this help message and exit` are all translatable.

In order to translate these strings, they must first be extracted into a `.po` file. For example, using Babel, run this command:

    $ pybabel extract -o messages.po /usr/lib/python3.12/argparse.py

This command will extract all translatable strings from the `argparse` module and output them into a file named `messages.po`. This command assumes that your Python installation is in `/usr/lib`.

You can find out the location of the `argparse` module on your system using this script:

    import argparse
    print(argparse.__file__)

Once the messages in the `.po` file are translated and the translations are installed using `gettext`, `argparse` will be able to display the translated messages.

To translate your own strings in the `argparse` output, use `gettext`.

## Custom type converters

The `argparse` module allows you to specify custom type converters for your command-line arguments. This allows you to modify user input before it’s stored in the `argparse.Namespace`. This can be useful when you need to pre-process the input before it is used in your program.

When using a custom type converter, you can use any callable that takes a single string argument (the argument value) and returns the converted value. However, if you need to handle more complex scenarios, you can use a custom action class with the action parameter instead.

For example, let’s say you want to handle arguments with different prefixes and process them accordingly:

    import argparse

    parser = argparse.ArgumentParser(prefix_chars='-+')

    parser.add_argument('-a', metavar='<value>', action='append',
                        type=lambda x: ('-', x))
    parser.add_argument('+a', metavar='<value>', action='append',
                        type=lambda x: ('+', x))

    args = parser.parse_args()
    print(args)

Вихід:

    $ python prog.py -a value1 +a value2
    Namespace(a=[('-', 'value1'), ('+', 'value2')])

In this example, we:

- Created a parser with custom prefix characters using the `prefix_chars` parameter.

- Defined two arguments, `-a` and `+a`, which used the `type` parameter to create custom type converters to store the value in a tuple with the prefix.

Without the custom type converters, the arguments would have treated the `-a` and `+a` as the same argument, which would have been undesirable. By using custom type converters, we were able to differentiate between the two arguments.

## Висновок

Модуль `argparse` пропонує набагато більше, ніж показано тут. Його документи досить докладні та ретельні та повні прикладів. Пройшовши цей підручник, ви повинні легко засвоїти їх, не відчуваючи себе приголомшеними.