Как не выйти из клика CLI? - PullRequest
0 голосов
/ 10 октября 2018

Я пишу скрипт на python, который должен вести себя как обычная оболочка и предоставляет некоторые самописные функции.Он уже работает достаточно хорошо, но он всегда завершается после успешной команды, поэтому его необходимо запустить снова для выполнения второго задания.Как я могу это сделать, чтобы он не заканчивался кодом завершения 0, а возвращался в оболочку в ожидании нового ввода?Как мне тогда реализовать методы выхода?Следующий пример всегда завершается после ввода print-a или print-b:

import click
import click_repl
from prompt_toolkit.history import FileHistory
import os

@click.group(invoke_without_command=True)
@click.pass_context
def cli(ctx):
     if ctx.invoked_subcommand is None:
         ctx.invoke(repl)

@cli.command()
def print_a():
    print("a")


@cli.command()
def print_b():
    print("b")


@cli.command()
def repl():
    prompt_kwargs = {
        'history': FileHistory(os.path.expanduser('~/.repl_history'))
    }
    click_repl.repl(click.get_current_context(), prompt_kwargs)

def main():
    while True:
        cli(obj={})


if __name__ == "__main__":
    main()

(И дополнительный вопрос: в пакете cmd можно настроить тег приглашения >, возможно ли это с помощью нажатияк? Так что это что-то вроде App> вместо?)

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

Используйте аргумент standalone_mode, попробуйте следующее:

rv = cli(obj={}, standalone_mode=False)

При сбое синтаксического анализа приведенный выше код выдаст UsageError.Когда --help было пройдено, rv будет целым числом 0.В большинстве других случаев возвращается возвращаемое значение функции, которая обрабатывает команду, хотя есть множество исключений, и поведение в целом довольно сложное, здесь больше объяснений: https://click.palletsprojects.com/en/master/commands/#command-return-values

Преимущество этогоПодход заключается в том, что вы можете использовать возвращаемые значения из обработчиков команд.Недостатком является то, что вы теряете симпатичное печатное сообщение справки при сбое анализа (может быть, есть способ восстановить его?).


Другой вариант - не использовать standalone_mode и вместо этого обернуть ваш вызов cli в блоке try/except, в котором вы ловите SystemExit:

try:
    cli(obj={})
except SystemExit as e:
    if e.code != 0:
        raise

Набрав SystemExit, вы можете остановить процесс выхода из программы, инициированный щелчком.Если команда успешно проанализирована, то SystemExit(0) перехватывается.Еще раз обратите внимание, что синтаксический анализ --help также считается «успешным» анализом и, следовательно, также возвращает SystemExit(0).

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

Следует также отметить, что SystemExit наследуется от BaseException, но не от Exception.Таким образом, чтобы поймать SystemExit, вы можете либо поймать его напрямую, либо поймать BaseException.

0 голосов
/ 10 октября 2018

Просто поместите весь свой код в цикл while

def main():
    # your code

while True:
    main()

Вы можете выйти из скрипта python с помощью Ctrl+C клавиатуры

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...