dir、tree、cd等等,都是我们常见的命令。这些命令是开发者开发出来的,如果我们自己想按照自己的想法开发一个命令,应该怎么做呢?
以python语言来实现,问题就是:如何使用python自定义命令?
需求场景如下:
1、cmd007 作为自定义命令名称
2、cmd007 hello --name=Lily 作为自定义功能1的名称hello打招呼,输出:Hi, Lily
3、cmd007 eat --food=fish 作为自定义功能2的名称food吃东西,输出:I like to eat fish
(一)目录结构如下:
cmd007 # 文件夹必须和自定义命令同名
│ __init__.py
│ __main__.py
(二)实现自定义命令和功能1
在__main__.py中
1 from __future__ import unicode_literals 2 import click 3 4 import os 5 import sys 6 7 __version__ = "1.1.dev2" 8 9 10 def verbose_option(f): 11 def callback(ctx, param, value): 12 pass 13 14 return click.option("-v", "--version", 15 is_flag=True, 16 expose_value=False, 17 help="Enable verbose output", 18 callback=callback)(f) 19 20 21 def quiet_option(f): 22 def callback(ctx, param, value): 23 pass 24 25 return click.option('-q', '--quiet', 26 is_flag=True, 27 expose_value=False, 28 help='Silence warnings', 29 callback=callback)(f) 30 31 32 def common_options(f): 33 f = verbose_option(f) 34 f = quiet_option(f) 35 return f 36 37 38 pgk_dir = os.path.dirname(os.path.abspath(__file__)) 39 40 41 @click.group(context_settings={'help_option_names': ['-h', '--help']}) 42 @click.version_option( 43 '{0} from {1} (Python {2})'.format(__version__, pgk_dir, sys.version[:3]), 44 '-V', '--version') 45 @common_options 46 def cli(): 47 """ 48 cmd007 - my cmd named cmd007 49 """ 50 51 52 # 自定义功能:hello 53 @cli.command(name="hello") 54 @click.option('-n', '--name', help="please input name") 55 @click.option('-c', '--count', help="print times", default=1) 56 def hello_command(name, count): 57 for x in range(count): 58 print("Hi, {0}".format(name)) 59 60 61 if __name__ == '__main__': 62 cli()
来到cmd007的上级目录下,调出命令行客户端,执行命名:
python cmd007
python cmd007 -V
python cmd007 hello --name=Lily --count=3
python cmd007 hello -n Lilei -c 2
分别输出:
提示:如果将这个python包cmd007打包发布,然后安装到python中去,那么每行命令就不用输入python关键字了。
(三)实现自定义命令、功能1、功能2
在__main__.py中增加代码
# 自定义功能2:eat
@cli.command(name="eat")
@click.option('-f', '--food', help="please input your like food")
@click.option('-a', '--and-you', help="ask echo other", default=False)
def hello_command(food, and_you):
print("I like to eat {0}".format(food))
if and_you in ['t', 'T', 'true', 'True', True, 1, "1"]:
print("And what is your favorite food ?")
完整版:
1 from __future__ import unicode_literals 2 import click 3 4 import os 5 import sys 6 7 __version__ = "1.1.dev2" 8 9 10 def verbose_option(f): 11 def callback(ctx, param, value): 12 pass 13 14 return click.option("-v", "--version", 15 is_flag=True, 16 expose_value=False, 17 help="Enable verbose output", 18 callback=callback)(f) 19 20 21 def quiet_option(f): 22 def callback(ctx, param, value): 23 pass 24 25 return click.option('-q', '--quiet', 26 is_flag=True, 27 expose_value=False, 28 help='Silence warnings', 29 callback=callback)(f) 30 31 32 def common_options(f): 33 f = verbose_option(f) 34 f = quiet_option(f) 35 return f 36 37 38 pgk_dir = os.path.dirname(os.path.abspath(__file__)) 39 40 41 @click.group(context_settings={'help_option_names': ['-h', '--help']}) 42 @click.version_option( 43 '{0} from {1} (Python {2})'.format(__version__, pgk_dir, sys.version[:3]), 44 '-V', '--version') 45 @common_options 46 def cli(): 47 """ 48 cmd007 - my cmd named cmd007 49 """ 50 51 52 # 自定义功能1:hello 53 @cli.command(name="hello") 54 @click.option('-n', '--name', help="please input name") 55 @click.option('-c', '--count', help="print times", default=1) 56 def hello_command(name, count): 57 for x in range(count): 58 print("Hi, {0}".format(name)) 59 60 61 # 自定义功能2:eat 62 @cli.command(name="eat") 63 @click.option('-f', '--food', help="please input your like food") 64 @click.option('-a', '--and-you', help="ask echo other", default=False) 65 def hello_command(food, and_you): 66 print("I like to eat {0}".format(food)) 67 if and_you in ['t', 'T', 'true', 'True', True, 1, "1"]: 68 print("And what is your favorite food ?") 69 70 71 if __name__ == '__main__': 72 cli()
执行
python cmd007 eat -f fish --and-you=1
输出
延伸:
@click.option()中的参数详解:https://blog.csdn.net/weixin_31866177/article/details/82111586
每个参数解释如下:
- name or flags - 选项字符串的名字或者列表,例如 foo 或者 -f, --foo。
- action - 命令行遇到参数时的动作,默认值是 store。
- store_const,表示赋值为const;
- append,将遇到的值存储成列表,也就是如果参数重复则会保存多个值;
- append_const,将参数规范中定义的一个值保存到一个列表;
- count,存储遇到的次数;此外,也可以继承 argparse.Action 自定义参数解析;
- nargs - 应该读取的命令行参数个数,可以是具体的数字,或者是?号,当不指定值时对于 Positional argument 使用 default,对于 Optional argument 使用 const;或者是 * 号,表示 0 或多个参数;或者是 + 号表示 1 或多个参数。
- const - action 和 nargs 所需要的常量值。
- default - 不指定参数时的默认值。
- type - 命令行参数应该被转换成的类型。
- choices - 参数可允许的值的一个容器。
- required - 可选参数是否可以省略 (仅针对可选参数)。
- help - 参数的帮助信息,当指定为
argparse.SUPPRESS
时表示不显示该参数的帮助信息. - metavar - 在 usage 说明中的参数名称,对于必选参数默认就是参数名称,对于可选参数默认是全大写的参数名称.
- dest - 解析后的参数名称,默认情况下,对于可选参数选取最长的名称,中划线转换为下划线.