Использование click для создания сложного интерфейса командной строки - PullRequest
1 голос
/ 09 февраля 2020

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

dbmgr.py create table --name="mytab"
dbmgr.py create view  --name="myview" --other-opt=...
dbmgr.py drop table --name=...
dbmgr.py drop user  --username=...

В этом случае есть предопределенный набор операций («создать», «отбросить» и т. Д. c), и каждая операция имеет спецификацию c предопределенный набор объектов, с которыми может работать каждая операция. В этом случае операция «create» может принимать только объект «table» или «view».

В случае операции «drop» пользователь может указать только объекты «table» и «user». В случае щелчка «создать», «таблица», «представление» и «отбросить» просто аргументы? Если так, как я могу ограничить то, что может быть указано для указанных c значений? Я не уверен, что в этом случае используются группы, команды и т. Д. c, и если да, то как?

1 Ответ

3 голосов
/ 09 февраля 2020

То, что вы пытаетесь сделать, это точный вариант использования для групп кликов . В вашем примере create и drop являются группами, а table, view, et c ... являются командами. Этот тип структуры (на мой взгляд) делает Click лучше, чем другие библиотеки анализа командной строки Python. Он может довольно хорошо описать эти структуры.

Пример кода:

import click

@click.group()
def cli():
    """DB Manager CLI"""

@cli.group()
def create():
    """create objects"""

@create.command()
def table():
    click.echo('create table command')

@create.command()
def view():
    click.echo('create view command')

@cli.group()
def drop():
    """create objects"""

@drop.command()
def table():
    click.echo('drop table command')

@drop.command()
@click.option('--username')
def user(username):
    click.echo('drop user command: {}'.format(username))

if __name__ == "__main__":
    cli()

Код теста:

if __name__ == "__main__":
    commands = (
        'create table',
        'create view',
        'drop table',
        'drop user --username a-user',
        '--help',
        'drop --help',
        'drop user --help',
    )

    import sys, time
    time.sleep(1)
    print('Click Version: {}'.format(click.__version__))
    print('Python Version: {}'.format(sys.version))
    for cmd in commands:
        try:
            time.sleep(0.1)
            print('-----------')
            print('> ' + cmd)
            time.sleep(0.1)
            cli(cmd.split())

        except BaseException as exc:
            if str(exc) != '0' and \
                    not isinstance(exc, (click.ClickException, SystemExit)):
                raise

Результаты:

Click Version: 7.0
Python Version: 3.8.1 (tags/v3.8.1:1b293b6, Dec 18 2019, 22:39:24) [MSC v.1916 32 bit (Intel)]
-----------
> create table
create table command
-----------
> create view
create view command
-----------
> drop table
drop table command
-----------
> drop user --username a-user
drop user command: a-user
-----------
> --help
Usage: test.py [OPTIONS] COMMAND [ARGS]...

  DB Manager CLI

Options:
  --help  Show this message and exit.

Commands:
  create  create objects
  drop    create objects
-----------
> drop --help
Usage: test.py drop [OPTIONS] COMMAND [ARGS]...

  create objects

Options:
  --help  Show this message and exit.

Commands:
  table
  user
-----------
> drop user --help
Usage: test.py drop user [OPTIONS]

Options:
  --username TEXT
  --help           Show this message and exit.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...