命令行模块——click(二)

命令行模块——click(二)

1.Click命令

命令是 Click 库中的核心部分,它们代表了我们可以在命令行中执行的不同操作。在 Click 中,我们可以通过使用 @click.command() 装饰器来定义一个命令,并使用函数体内的代码来实现该命令的功能。例如:

import click

@click.command()
def hello():
    click.echo("Hello, world!")

在上面的例子中,我们使用 Click 的 @click.command() 装饰器来定义了一个名为 hello 的命令,该命令不接收任何参数,如果代码写在demo.py当执行python demo.py时,会输出“Hello, world!”的信息。一般来说,我们会给命令添加参数和选项,也就是在之前的文章中所写的那样。

2.Click命令组

命令组是 Click 库中用于组织一组相关命令的工具。它允许将一组命令作为一个整体进行操作,并且可以方便地进行嵌套和组合。在 Click 中,我们可以通过 click.group() 装饰器来定义一个命令组,并使用 @click.command() 装饰器来定义该组内的命令。

下面是一个使用命令组的示例,其中我们定义了一个名为 cli 的命令组,并将两个子命令 initstatus 添加到该组中:

import click

@click.group()
def cli():
    pass

@cli.command()
def init():
    click.echo("Initialized the database")

@cli.command()
def status():
    click.echo("Status of the database")


if __name__ == "__main__":
    cli()

当我们命令窗执行python demo.py init输出为:Initialized the database。在上面的代码中,我们首先使用 click.group() 装饰器定义了一个名为 cli 的命令组,然后使用 command() 方法为该组添加了两个子命令 initstatus。当用户在命令行中输入 python demo.py 时,程序会默认执行 cli 命令组中的逻辑,并按需调用子命令。

多组命令的情况:一个模块中包含多个命令组,也就是模块中定义多个装饰了 click.group() 的函数,每个函数对应一个命令组。同时,也可以在每个命令组下面定义多个子命令,使用 @click.command() 装饰器来为命令组添加子命令。

更加复杂的情况:

import click


@click.group()
def cli():
    """Main tool"""


@cli.group()
def cmd():
    """Command sub-group"""


@cmd.command()
def init():
    """Initialize"""
    print('Init')


@cli.group()
def config():
    """Configuration sub-group"""


@config.group()
def network():
    """Network configuration"""


@network.command()
def ip():
    """Set IP address"""
    print('Set IP')


@network.command()
def subnet():
    """Set subnet mask"""
    print('Set subnet mask')


def main():
    cli()
    # cmd()
    # config()
    # network()


if __name__ == '__main__':
    main()

在这个示例中,我们定义了一个命令行接口,包含:- 命令组cli作为主入口
- cli下面有两个子命令组cmd和config
- cmd下面有一个子命令init
- config下面又有一个子命令组network
- network下面有两个子命令ip和subnet所以整个命令行接口的结构如下:

在这里插入图片描述

这里调用的时候就用注意啦!从以上的结构上可以看出来,命令cmd和config是依附于cli的,所以在main中调用了cli,在命令窗中输入:python demo.py config network subnet,可以看到不用在写上cli,cli是默认执行的,只需要指明器子命令,子命令下的子命令即可。这就引发了我的好奇,是不是我在main中调用cmd和config可以默认执行呢?所以进行了尝试,在命令窗中运行了:python demo.py init,报错Error: No such command 'init',看来就算在main中直接吊用了cmd,cmd也不是像cli那样默认执行的,这个要注意。其他情况也是同理,就算是在main中调用了config也不能直接输入python demo.py network subnet,否则报错,调用subnet需要python demo.py config network subnet

再举一个例子说明一下:

import click

@click.group()
def cli1():
    """Main command line tool"""

@cli1.group()  
def cli2():
    """Sub command group"""

@cli2.command()
def init():
    """Initialize"""
    print('Init')

@cli1.group()
def cli3():
    """Other sub command group"""  

@cli3.command()
def add():
    """Add item"""
    print('Add')

def main():
    cli1()
    cli2()
    cli3()

if __name__ == '__main__':
    main()

在这个示例中,我们定义了:- 命令组cli1作为根命令组
- cli1下面有两个子命令组cli2和cli3
- cli2下面有子命令init
- cli3下面有子命令add

在main函数中,我们按嵌套结构注册了所有命令组:cli1 -> cli2 -> cli3

所以在命令行可以这样调用:

python file.py 
# 只调用cli1根命令组,等待子命令

python file.py cli2 init
# cli1 -> cli2 -> init 
输出:Init

python file.py cli3 add  
# cli1 -> cli3 -> add
输出:Add 

以上就是命令组的一些知识梳理。

还有一点我在代码中遇到的这里补充一下。一个与click有关的装饰器@xx.result_callback(),其中xx是定义好的函数。具体举一个例子来说明一下这个装饰器的用法和作用。

import click


@click.group()
# @click.option("--a", type=int)
# @click.option("--b", type=int)
@click.argument("a", type=int)
@click.argument("b", type=int)
def cli(**kwargs):
    pass


@cli.result_callback()
def add(haha, a, b):
    c = a+b
    print("Welcome!!!", c)


@cli.command()
def end():
    click.echo("the end")


if __name__ == "__main__":
    cli()

以上例子中@cli.result_callback(show_result)用于为命令定义结果回调函数。回调函数的就是不用专门调用,执行的时候是默认的。这里在学习它的时候遇到了一些问题,这里记录一下。首先使用回调函数的时候使用的是@click.group()装饰器,放在主函数前,其次,要回调的函数要是使用@xx.result_callback(),其中xx表示主函数名字,还用回调函数中的参数要在主函数前就用@click.option@click.argument就定义好,如果在回调函数前定义,会报错。最后,主函数要有子命令这个代码的子命令是end函数,使用前要用@cli.command()装饰器(如果没有写子命令,会报错)。回调函数中的参数是@click.option@click.argument定义好的,其实最开始这个回调程序我是这样写的:

 def add(a, b):
    c = a+b
    print("Welcome!!!", c)

调用时python demo.py 2 20 end报错:TypeError: add() got multiple values for argument 'a'逻辑是对的为啥会出现这样的错误,很不理解。就查,但是跟这个关系都不太大。既然说是参数有问题,就鬼使神差的,我就这个函数中加了一个参数(这个参数之前也没有定义),就不报错了,但是不知道为啥。反正下次再使用回调函数的时候,再用出现这样的错误就知道咋改了。

以上就是我用到的关于click命令模块之后总结的东西。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值