Python脚本进阶 - Click模块

419 阅读3分钟

1. 命令行与脚本

1.1 脚本的不足

  1. 用户需要手动安装依赖
  2. 涉及到多个脚本,需要手动分发多个脚本
  3. 脚本对于环境的一致性要求比较高,分发时需要确保环境一致
  4. 脚本不放置在系统路径中。需要使用完整路径调用
  5. 脚本无法配置子命令,使用起来比较麻烦
  6. 脚本需要自行维护参数args
  7. 脚本没有提供原生的帮助信息,长期维护成本高

1.2 命令行工具的选型

  1. cement
  2. Click
  3. cliff
  4. docopt
  5. python-fire
  6. python-prompt-toolkit

2. Click命令行工具

2.1 Click介绍

  • Click 是一个以尽可能少的代码,以组合的方式创建优美的命令行程序的Python包它有很高的可配置性。同时也能开箱即用。

  • Click具备以下三个特性

    • 任意嵌套命令
    • 自动生成帮助
    • 支持运行时坚持加载子命令
  • 快速开始

    import click
    ​
    ​
    @click.command()
    def hello():
        click.echo("hello world!")
    ​
        
    if __name__ == '__main__':
        hello()
    
    (.env) ➜  click python hello.py 
    hello world!
    

2.2 Click选项

在Click中,可以使用click .option来定义选项

  • option 中设置default为默认选项
  • option 中设置help为帮助信息
  • option 设置type为数据类型
  • option 设置hide_input 可以隐藏输入
  • option 设置confirmation_prompt可以验证输入
  • option 设置nargs表示接受多个值
import click
​
​
@click.command()
@click.option('--count', default=1, type=int, help='Number of greetings.')
@click.option('--name', prompt='Your name', help='The person of greet.')
def hello(count, name):
    click.echo(count)
    click.echo(name)
    click.echo("hello world!")
​
​
if __name__ == '__main__':
    hello()
(.env) ➜  click python hello.py --name=du            
1
du
hello world!

2.3 Click定义参数Argument

在Click中,可以使用click.argument来定义参数

  • argument 设置nargs 表示接受多个值
  • argument 设置type设定格式
  • argument 设置type为click.File支持对文件操作
import click
​
@click.command()
@click.argument('action', type=str)
@click.option('--count', default=1, type=int, help='Number of greetings.')
@click.option('--file', type=click.File(), help='File')
def hello(action, count, file):
    click.echo(action)
    click.echo(count)
    click.echo(file)
    click.echo("hello world!")
​
​
if __name__ == '__main__':
    hello()
(.env) ➜  click python hello.py --help                 
Usage: hello.py [OPTIONS] ACTION
​
Options:
  --count INTEGER  Number of greetings.
  --file FILENAME  File
  --help           Show this message and exit.
(.env) ➜  click python hello.py start --file=hello.py
start
1
<_io.TextIOWrapper name='hello.py' mode='r' encoding='UTF-8'>
hello world!

2.4 Click接受的参数类型

Click 可以接受以下类型数据作为参数

  • str : 字符串
  • int : 数值
  • float : 浮点數
  • bool : 布尔值
  • click.JUID : UUID值
  • click.File : 文件类型
  • click.Path : 文件路径类型
  • click.Choice : 可选项类型
  • click.IntRange : 数值可选范围
  • click.FloatRange : 浮点数可选范围
  • click.DateTime : 时间

2.5 Click获取用户输入Prompt

  • Click 提供了dick.prompt要求用户输入
  • Click 提供了dlick.confirm要求用户确认
import click
​
​
@click.command()
def hello():
    count = click.prompt('please input a int', type=int)
    click.echo(count)
    click.echo("hello world!")
    if click.confirm('do you want to continue?'):
        click.echo('done')
​
​
if __name__ == '__main__':
    hello()
(.env) ➜  click python hello.py
please input a int: 100
100
hello world!
do you want to continue? [y/N]: y
done

3. Click高级用法

3.1 Click彩色化

Click内置了输出颜色的功能,开发者可以很轻松的完成对文字进行美化,从而提升输出内容的醒目程度

import click


@click.command()
def hello():
    click.echo(click.style("hello world!", fg='green'))
    click.echo(click.style("some more text", bg='blue', fg='white'))
    click.echo(click.style("ATTENTION", blink=True, bold=True))

    click.secho('hello world!', fg='green')
    click.secho("some more text", bg='blue', fg='white')
    click.secho("ATTENTION", blink=True, bold=True)


if __name__ == '__main__':
    hello()

3.2 Click分页

Click内置了分页内容的支持,你可以十分方便的完成内容的分页展示;对于内容特别大方,可以使用迭代器来实现

import click


def _generate_output():
    for idx in range(50000):
        yield f'Line {idx}\n'

@click.command()
def less():
    click.echo_via_pager(_generate_output())


if __name__ == '__main__':
    less()

3.3 Click进度条

Click提供了一个进度的功能,在处理大量文件时,可以快速实现一个简单的进度条

import click
import time

all_the_users_to_process = ['a', 'b', 'c']

def modify_the_user(user):
    time.sleep(1)

@click.command()
def progressbar():
    with click.progressbar(all_the_users_to_process) as bar:
        for user in bar:
            modify_the_user(user)


if __name__ == '__main__':
    progressbar()

3.4 不常用的命令

  1. Click清除屏幕

如果你需要清空屏幕提示内容,可以使用click.clear()函数,清空屏幕上现有的内容

  1. Click 等待用户按键

如果你需要在执行完成后,等待用户按键再执行命令,可以简单的调用click.pause()方法实现等待用户按键的功能