Ara*_*ght 3 python command-line-interface python-3.x
我正在编写一个 python 脚本,它的行为应该像一个典型的 shell 并提供一些自写函数。它已经工作得很好,但它总是在成功执行命令后退出,因此必须再次启动它才能执行第二个任务。我怎样才能做到,所以它不会以退出代码 0 结束,而是返回到 shell 等待新输入?那么我将如何实现退出方法?以下示例总是在输入 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()
Run Code Online (Sandbox Code Playgroud)
(还有一个额外的问题:在 cmd 包中可以自定义>提示标签,这可以通过单击来实现吗?所以它是类似的东西App>?)
使用standalone_mode参数,试试这个:
rv = cli(obj={}, standalone_mode=False)
Run Code Online (Sandbox Code Playgroud)
当解析失败时,上面的代码会抛出一个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
Run Code Online (Sandbox Code Playgroud)
通过捕获,SystemExit您可以停止由单击启动的程序退出过程。如果命令解析成功,SystemExit(0)则被捕获。再次注意,解析--help也算作“成功”解析,因此也返回SystemExit(0).
这种方法的缺点是您不能使用命令处理程序的返回值,这使得更难知道何时--help被传递。好处是所有到控制台的帮助消息都被恢复了。
我还应该注意到SystemExit继承自BaseException但不是来自Exception. 因此,要实际捕获,SystemExit您可以直接捕获它或 catch BaseException。