python - Python Click - 如果父命令成功执行,则仅执行子命令
问题描述
我正在使用Click构建 Python CLI,并且遇到了如何在 Click 中处理异常的问题。
我不确定这里的措辞(“subcommand”,“parentcommand”),但从我的例子中你会得到我希望的想法。让我们假设这段代码:
@click.group()
@click.option("--something")
def mycli(something):
try:
#do something with "something" and set ctx
ctx.obj = {}
ctx.obj["somevar"] = some_result
except:
print("Something went wrong")
raise
#only if everything went fine call mycommand
@click.group()
@click.pass_context
def mygroup(ctx):
pass
@mygroup.command(name="mycommand")
@click.pass_context
def mycommand(ctx):
#this only works if somevar is set in ctx so don't call this if setting went wrong in mycli
当应用程序启动时,它被调用:
if __name__ == "__main__":
mycli.add_command(mygroup)
mycli()
然后我像这样启动程序:
python myapp --something somevalue mycommand
预期行为:首先mycli
调用并执行其中的代码。如果抛出异常,它会被 except 块捕获,会打印一条消息并引发异常。因为我们没有其他 try/except 块,这将导致脚本终止。“sub”-commandmycommand
永远不会被调用,因为程序在运行“parent”-command 时已经终止mycli
。
实际行为:异常被捕获并打印消息,但mycommand
仍被调用。然后它失败并显示另一个异常消息,因为未设置所需的上下文变量。
我将如何处理这样的事情?基本上我只想在mycommand
一切正常的情况下调用子命令才能执行mycli
。
解决方案
要处理异常,但不继续执行子命令,您可以简单地调用exit()
如下:
代码:
import click
@click.group()
@click.option("--something")
@click.pass_context
def mycli(ctx, something):
ctx.obj = dict(a_var=something)
try:
if something != '1':
raise IndexError('An Error')
except Exception as exc:
click.echo('Exception: {}'.format(exc))
exit()
测试代码:
@mycli.group()
@click.pass_context
def mygroup(ctx):
click.echo('mygroup: {}'.format(ctx.obj['a_var']))
pass
@mygroup.command()
@click.pass_context
def mycommand(ctx):
click.echo('mycommand: {}'.format(ctx.obj['a_var']))
if __name__ == "__main__":
commands = (
'mygroup mycommand',
'--something 1 mygroup mycommand',
'--something 2 mygroup mycommand',
'--help',
'--something 1 mygroup --help',
'--something 1 mygroup mycommand --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)
mycli(cmd.split())
except BaseException as exc:
if str(exc) != '0' and \
not isinstance(exc, (click.ClickException, SystemExit)):
raise
结果:
Click Version: 6.7
Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]
-----------
> mygroup mycommand
Exception: An Error
-----------
> --something 1 mygroup mycommand
mygroup: 1
mycommand: 1
-----------
> --something 2 mygroup mycommand
Exception: An Error
-----------
> --help
Usage: test.py [OPTIONS] COMMAND [ARGS]...
Options:
--something TEXT
--help Show this message and exit.
Commands:
mygroup
-----------
> --something 1 mygroup --help
Usage: test.py mygroup [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
mycommand
-----------
> --something 1 mygroup mycommand --help
mygroup: 1
Usage: test.py mygroup mycommand [OPTIONS]
Options:
--help Show this message and exit.
推荐阅读
- java - 没有密码的RSA加密私钥?
- android - AppBar Flutter 顶部的黑条
- sql - 以特定顺序更新表的一个查询
- php - mysqli_real_escape_string() 期望参数 2 是字符串?
- python - 预处理脚本不删除标点符号
- html - 如何不加载 Index.html?
- python-3.x - AttributeError:模块“tensorflow.python.keras.api._v2.keras.backend”没有属性“set_image_dim_ordering”
- java - 在 Spring Boot 中运行 Junit 测试用例时的初始化
- tensorflow - self_adjoint_eig 的问题
- google-cloud-firestore - 集合查询(单个)是否比 groupCollection 查询更快?