我正在编写一个命令行脚本
然而,如果不存在
如果用户运行
mycli
,其中包括两个子命令:
mkcli init
(用于初始化空项目并生成.configrc
文件)mkcli run
(运行脚本的主要逻辑)。
.configrc
文件,则mycli run
将无法工作。但是,我的用户应该能够查看run
的帮助信息:$ mycli run --help
Usage: mycli run [OPTIONS]
Options:
--dryrun Run in read-only mode
--help Show this message and exit.
然而,如果不存在
.configrc
文件,则无法工作,因为在组命令cli
中引发FileNotFoundError
(并且永远不会到达run
)。我可以使用ctx.invoked_subcommand
(见下文)在找到.configrc
文件之前启动init
子命令,但我看不到确保始终启动run
子命令的方法,即使它使用--help
调用。如果用户运行
mkcli run
并且找不到.configrc
文件,则我的脚本将退出,并显示run "mycli init" first
。但是,即使没有.configrc
,mycli run --help
也应该正常工作。我该如何做到这一点?或者有人能建议更好的处理init
的方法吗?@click.group()
@click.pass_context
def cli(ctx):
ctx.obj = {}
if ctx.invoked_subcommand != "init":
config = yaml.load(open(".configrc").read())
ctx.obj.update({key: config[key] for key in config})
@cli.command()
@click.pass_context
def init(ctx):
print("Initialize project.")
@cli.command()
@click.option("--dryrun", type=bool, is_flag=True, help="Run in read-only mode")
@click.pass_context
def run(ctx, dryrun):
print("Run main program here.")
init
(init --with-examples
),这也可以正常工作(应该是这样)。但我不明白为什么它能工作。decorator(f)
是如何被调用的,f
又从哪里来的? - Tom Baker@cli.command()
时,会调用decorator(f)
。简而言之:cli.command()
返回decorator
,然后@
调用decorator(f)
,其中f
是被装饰的函数。这个链接可能会有所帮助:https://www.learnpython.org/en/Decorators - Stephen Rauch的语法 - 我从未见过带有两组括号的函数调用(并且仍然不确定它是如何解析的)。我是否正确理解每次运行
Group.command()`时,“装饰器”函数都会将被装饰的函数作为参数“f”传递?感谢您将答案与测试打包 - 非常有帮助! - Tom Baker