Необязательные аргументы CLI с python Нажмите кнопку библиотеки - PullRequest
1 голос
/ 18 марта 2020

У меня загадка с библиотекой Python Click при разборе некоторых параметров CLI.

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

  1. $ myscript ⇒ option = False

  2. $ myscript -o ⇒ option = True

  3. $ myscript -o foobar ⇒ option = Foobar

Кроме того, я бы хотел, чтобы опция была "нетерпеливой" (например, в терминах "Click" отменить выполнение после обратного вызова), но это может пока что меня игнорируют.


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

@click.command()
@click...
@click.option("-o", "option", is_flag=True, default=False)
def myscript(..., option):

Я достигаю примеров 1 и 2, но 3, естественно, невозможно, потому что флаг обнаруживает присутствие / отсутствие только настоящее.


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

@click.command()
@click...
@click.option("-o", "--option", default="") # Let's assume I will cast empty string to False
def myscript(..., option):

Я получаю 1 и 3, но 2 завершится с Error: -c option requires an argument.


Это не похоже на сценарий из этого мира, но я не могу достичь этого или найти примеры, которые ведут себя так.

Как я могу определить @click.option, который анализируется как:

  • False, если не задано
  • True, когда установлено, но без значения
  • str, если задано значение

1 Ответ

1 голос
/ 24 марта 2020

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

@click.command(context_settings={"ignore_unknown_options": True})
@click.argument("options", nargs=-1)
def myscript(options):
    option = False
    if options is ():
        option = False
    if '-o' in options or '--option' in options:
        option = True
    if len(options) > 1:
        option = options[1]
    print(option)

Позже Редактирование Использование Я смог добиться этого, добавив аргумент в определение команды.

@click.command()
@click.option('-o', '--option', is_flag=True, default=False, is_eager=True)
@click.argument('value', nargs=-1)
def myscript(option, value):
    if option and value != ():
        option = value[0]
    print(option)

nargs можно удалить, если ожидается, что последует не более одного аргумента, и его можно рассматривать как не требуется.

@click.command()
@click.option('-o', '--option', is_flag=True, default=False, is_eager=True)
@click.argument('value', required=False)
def myscript(option, value=None):
    if option and value is not None:
        option = value
    print(option)

Это также может быть возможно путем объединения генератора контекста и сохранения некоторого состояния, но это кажется наименее желательным решением, поскольку вы полагаетесь на контекст, хранящий ваше состояние.

...