Глава 23 · Часть III · Создаём Python-проект

Командная строка SafeSort

argparse разбирает пять подкоманд SafeSort и связывает каждую с отдельной функцией-обработчиком.

SafeSort · Часть 3 из 6Проект
src/safesort/
__init__.py
cli.pyНОВОЕ
Первый файл с настоящей логикой: cli.py.

SafeSort будет управляться пятью подкомандами: scan, plan, apply, duplicates и undo. За разбор аргументов командной строки отвечает модуль argparse из стандартной библиотеки — он же формирует текст --help.

src/safesort/cli.py
def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        prog="safesort",
        description=(
            "SafeSort: a safe, non-destructive file organizer. "
            "scan/plan/duplicates are read-only; 'apply' sorts and 'undo' restores files."
        ),
    )
    subparsers = parser.add_subparsers(dest="command", required=True)

    scan_parser = subparsers.add_parser("scan", help="...")
    scan_parser.add_argument("root", type=Path, help="Directory to scan.")
    # ...аналогично для plan, apply, duplicates, undo
    return parser
add_subparsers(dest="command", required=True)
dest="command" кладёт название вызванной подкоманды в args.command. required=True заставляет argparse самостоятельно вывести понятную ошибку, если пользователь запустит safesort вообще без подкоманды, — писать эту проверку вручную не нужно.

От разобранных аргументов к результату

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

src/safesort/cli.py
_HANDLERS = {
    "scan": cmd_scan,
    "plan": cmd_plan,
    "apply": cmd_apply,
    "duplicates": cmd_duplicates,
    "undo": cmd_undo,
}

def main(argv: list[str] | None = None) -> int:
    parser = build_parser()
    args = parser.parse_args(argv)
    handler = _HANDLERS[args.command]
    return handler(args)

Такой словарь — тот же приём, что и в игре «Камень, ножницы, бумага» из приложения к этой главе: вместо цепочки if args.command == "scan": ... elif ... нужную функцию просто ищут по ключу.

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

Установим пакет и запустим команду — argparse уже формирует текст помощи сам, без единой написанной вручную строки:

~/safesort $ safesort --help
usage: safesort [-h] {scan,plan,apply,duplicates,undo} ...
 
SafeSort: a safe, non-destructive file organizer. scan/plan/duplicates are
read-only; 'apply' sorts and 'undo' restores files.
 
positional arguments:
{scan,plan,apply,duplicates,undo}
scan List files found under ROOT, grouped by category
(read-only).
plan Show the moves that would be made under ROOT, without
changing anything (read-only).
apply Move files under ROOT into Sorted/<category>/ and
record an undo manifest.
duplicates Report groups of files with identical content under
ROOT (read-only, never deletes).
undo Undo the most recent 'apply' run recorded under ROOT.
 
options:
-h, --help show this help message and exit
Практика: разбор аргументов командной строки
Интерактивный ноутбук в браузере: Python 3.14 через Pyodide, без установки
Открыть практику →
Официальная документация
argparse — Parser for command-line options

Коротко

  • argparse.ArgumentParser с add_subparsers() разбирает пять подкоманд SafeSort и сам формирует текст --help.
  • dest="command" кладёт имя вызванной подкоманды в args.command; словарь _HANDLERS связывает это имя с нужной функцией.
  • Каждый обработчик возвращает 0 при успехе и ненулевое значение при ошибке — это код возврата всей программы.