Argparse - парсим аргументи і параметри командного рядка з легкістю

Починаючи з версії Python 2.7, до набору стандартних бібліотек було включено бібліотеку argparse для обробки аргументів (параметрів, ключів) командного рядка. Хотілося б припинити на ній Вашу увагу. Для початку розглянемо, що цікавого пропонує argparse.

Argparse - це витончений інструмент для:

  • аналізу аргументів sys.argv;
  • конвертування рядкових аргументів в об'єкти Вашої програми та робота з ними;
  • форматування та виведення інформативних підказок;
  • багато чого іншого.

Одним із аргументів противників включення argparse в Python був доказ про те, що в стандартних модулях і без цього міститься дві бібліотеки для семантичної обробки (парсингу) параметрів командного рядка. Однак, як заявляють розробники argparse, бібліотеки getopt та optparse поступаються argparse з кількох причин:

  • Маючи всю повноту дій зі звичайними параметрами командного рядка, де вони вміють обробляти позиційні аргументи (positional arguments). Позиційні аргументи — це аргументи, які впливають роботу програми, залежно від порядку, де вони у цю програму передаються. Найпростіший приклад - програма cp, що має мінімум 2 таких аргументи ("cp source destination").
  • argparse дає на виході якісніші повідомлення про підказку при мінімумі витрат (у цьому плані при роботі з optparse часто можна спостерігати деяку надмірність коду);
  • argparse дає можливість програмісту встановлювати собі які символи є параметрами, а які ні. На відміну від нього, optparse вважає опції з синтаксисом на кшталт "-pf, -file, +rgb, /f і т.п. "внутрішньо суперечливими" і "не підтримується optpars'ом і ніколи не буде";
  • argparse дасть Вам можливість використовувати декільказначень змінних в одному аргументі командного рядка (nargs);
  • argparse підтримує субкоманди (subcommands). Це коли основний парсер відсилає до іншого (субпарсер) залежно від аргументів на вході.

Для початку роботи з argparse необхідно задати парсер:

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

Якщо дію (action) для даного аргументу не задано, то за умовчанням він буде зберігатися (store) в namespace, причому ми можемо вказати тип цього аргументу (int, boolean і тд). Якщо ім'я аргументу, що повертається (dest) задано, його значення буде збережено у відповідному атрибуті namespace.

Простий приклад програми, що зводить квадрат значення позиційного аргументу (square) і формує висновок залежно від аргументу опціонального (-v):

Зупинимося на діях (Actions ). Вони можуть бути такими:— store: повертає у простір імен значення (після необов'язкового наведення типу). Як мовилося раніше, store — дія за промовчанням;

— store_const: в основному використовується для прапорів. Або поверне Вам значення, вказане в const, або (якщо не вказано), None. Приклад:

- store_true / store_false: аналог store_const, але для булевих True і False;

— append: повертає список шляхом додавання до нього значень агрументів. Приклад:

— append_const: повернення значення, визначеного у специфікації аргументу, до списку. Поки що у мене не було кейсу, в якому знадобився append_const.

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

Залежно від переданого в конструктор парсерааргументу add_help (бульового типу), буде визначатися, включати або не включати стандартний висновок за ключами ['-h', '--help'] повідомлення про допомогу. Те саме буде мати місце з аргументом version (рядкового типу), ключі за умовчанням: ['-v', '--version']. За запитом допомоги або номера версії подальше виконання переривається.

Зауважте, що батьківський парсер створюється з параметром add_help=False. Це зроблено тому, що кожен парсер чесно намагатиметься додати свій обробник ключа '-h', чим викличе конфліктну ситуацію. Звідси виникає питання, що робити, якщо ваш дочірній парсер має ті ж ключі, що й батьківський і при цьому ви хочете їх використовувати без будь-яких конфліктів? Це робиться простим додаванням аргументу conflict_handler:

Крім вищеописаного підходу до обробки команд різного рівня, є ще й альтернативний підхід, що дозволяє об'єднати обробку всіх команд в одній програмі, використовуючи субпарсери (subparsers). Найкраще сам за себе розповість приклад:

Ось що видасть програма з ключем '-h':

positional arguments: list of commands list List contents create Create a directory

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

У прикладі можна назвати такі речі: 1. позиційні аргументи list, create, які передаються програмі - по суті субпарсери; 2. аргумент '--read-only' субпарсера create_parser - опціональний, dir_name - необхідний для обох субпарсерів; 3. передбачена довідка (допомога) як для парсера, так і для кожного із субпарсерів.

Взагалі, argparse — досить потужна і легка бібліотека, яка на мій погляд дуже зручний інтерфейс для роботи з параметрами командного рядка. Наступного разу постараюсяохопити такі питання, як файлові аргументи (для більш просунутої роботи з файлами), змінні списки аргументів, групи аргументів і детальніше зупинитися на типізації аргументів. Дякую за увагу.

А у нас тут можна отримати грант на тестовий період Яндекс.Хмари. Варто лише у полі «секретний пароль» запровадити «Хабр»