PySpider原始碼分析(一)之run.py之click

Tbxsx發表於2018-05-11

簡要介紹

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函式。

相關文章