Python Click: несколько аргументов пары значений ключей - PullRequest
0 голосов
/ 04 июля 2018

Я использую библиотеку Python Click для моего интерфейса командной строки. Я хотел бы иметь команду, которая принимает несколько пар ключ-значение. Я гибкий на API. Например

my_cli my_command FOO=1 BAR=2

или, может быть,

my_cli my_command FOO 1 BAR 2

или даже

my_cli my_command {"FOO": 1, "BAR": 2}

Есть ли простой способ сделать это с помощью Click?

1 Ответ

0 голосов
/ 04 июля 2018

Самое простое решение - это то же самое, что и обычная функция Python, для которой вам нужен такой API.

Возьмите единственный параметр, который группирует поток аргументов переменной длины в кортеж. Затем то, что вы делаете, зависит от того, хотите ли вы отдельные аргументы:

>>> def func(*args):
...     d = dict(zip(args[::2], args[1::2]))
...     print(d)
>>> func('FOO', 1, 'BAR', 2)
{'FOO': 1, 'BAR': 2}

… или комбинированные key:value аргументы:

>>> def func(*args):
...     d = dict(arg.split(':') for arg in args)
...     print(d)

Это немного хакерский в использовании, потому что в Python аргументы - это не просто слова, разделенные пробелами, но имейте в виду:

>>> func('FOO:1', 'BAR:2')
{'FOO': 1, 'BAR': 2}

Эквивалент click для первого выглядит следующим образом:

@click.command()
@click.argument('args', nargs=-1)
def my_command(args):
    d = dict(zip(args[::2], args[1::2]))
    click.echo(d)

(Очевидно, вы можете вставить это в click.group и т. Д., Как и любая другая команда.)

А сейчас:

$ ./clicky.py FOO 1 BAR 2
{'FOO': 1, 'BAR': 2}

А второй выглядит так:

@click.command()
@click.argument('args', nargs=-1)
def my_command(args):
    d = dict(arg.split(':') for arg in args)
    click.echo(d)

И обратите внимание, что теперь его использование вовсе не является хакерским, потому что для вашей оболочки аргументы - это просто слова, разделенные пробелами:

$ ./clicky.py FOO:1 BAR:2
{'FOO': 1, 'BAR': 2}

Что делать, если вы хотите обрабатывать KEY=VALUE и KEY:VALUE? Тогда вам просто нужно написать что-то более сложное, чем arg.split(':'). И вам, вероятно, также понадобится лучшая обработка ошибок. Но этого должно быть достаточно, чтобы вы начали.

...