欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PySpider源码分析(一)之run.py之click

程序员文章站 2022-05-14 15:54:40
...

简要介绍

Pyspider中使用到了click作为其命令行的解析,在Python中有模块Argparse用于命令行解析,但相比于click,后者要强大且简介很多。这里结合Pyspider的run.py来学习click库。

click的常用命令。

@click.command() 装饰函数,使该函数变为可执行的命令行接口。
@click.group() 装饰函数,将其他被@click.command()的函数嵌入该函数内,使得出现层级命令。
@click.option() 装饰函数,为函数提供可选参数。
@click.argument() 装饰函数,为函数提供必选参数。
复制代码

比如说:

import click

@click.group(invoke_without_command=True)
@click.option("--config", type=int,default=5)
@click.pass_context
def cli(ctx, **kwargs):
    print("cli context")
    print(kwargs)

@cli.command()
@click.pass_context
def command1(ctx):
    print("command1 context")

@cli.command()
@click.pass_context
def command2(ctx):
    print("command2 context")

def main():
    cli()

if __name__ == "__main__":
    main()

复制代码

在shell中执行

$python3 example1.py --help #自动生成帮助命令
Usage: example2.py [OPTIONS] COMMAND [ARGS]...

Options:
  --config INTEGER
  --help            Show this message and exit.

Commands:
  command1
  command2

$python3 example1.py #默认执行
cli context
{'config': 5}

$python3 example1.py  --config 8 #设置config为8
cli context
{'config': 8}

$python3 example1.py  command1 #执行command1,注意command1会在cli函数之后执行
cli context
{'config': 5}
command1 context

复制代码

对于@click.option()我们可以自定义callback,对输入的值进行改变,如:

import click
import six


def read_config(ctx, params, value):
    if value is None:
        return {}
    import json
    config = json.load(value)
    ctx.default_map = config
    return config


@click.group(invoke_without_command=True)
@click.option("--num", default=5, type=int)
@click.option("--config", callback=read_config, type=click.File("r"))
@click.pass_context
def cli(ctx, **kwargs):
    print("cli context")
    print(kwargs)


@cli.command()
@click.pass_context
def command1(ctx,**kwargs):
    print("command1 context")
    print(kwargs)


@cli.command()
@click.pass_context
def command2(ctx):
    print("command2 context")


def main():
    cli()


if __name__ == "__main__":
    main()

复制代码

其中--configjson只读文件:

{
    "taskdb": "mongodb+taskdb://127.0.0.1:27017/pyspider_taskdb",
    "projectdb": "mongodb+projectdb://127.0.0.1:27017/pyspider_projectdb",
    "resultdb": "mongodb+resultdb://127.0.0.1:27017/pyspider_resultdb",
    "message_queue": "redis://127.0.0.1:6379/db",
    "webui": {
        "port": 5000
    }
}

复制代码
$python3 example1.py --config ./config.json --num 8
cli context
{
    'num': 8, 
    'config': {
        'taskdb': 'mongodb+taskdb://127.0.0.1:27017/pyspider_taskdb', 
        'resultdb': 'mongodb+resultdb://127.0.0.1:27017/pyspider_resultdb', 
        'projectdb': 'mongodb+projectdb://127.0.0.1:27017/pyspider_projectdb', 
        'webui': {
            'port': 5000
            
        }, 
        'message_queue': 'redis://127.0.0.1:6379/db'
    }
}

复制代码

可以看出文件内容作为value传入callback,再由callback经过处理返回cli函数。