Python命令行解析庫——argarse、docopt、click、invoke
阿新 • • 發佈:2018-05-16
argarse、docopt、click命令行示例:
基本用法
$ python [file].py hello Kyle Hello, Kyle! $ python [file].py goodbye Kyle Goodbye, Kyle!
W/選項用法(標誌)
$ python [file].py hello --greeting=Wazzup Kyle Whazzup, Kyle! $ python [file].py goodbye --greeting=Later Kyle Later, Kyle! $ python [file].py hello --caps Kyle HELLO, KYLE! $ python [file].py hello --greeting=Wazzup --caps Kyle WAZZUP, KYLE!
Argarse:標準庫
def greet(args): output = '{0}, {1}!'.format(args.greeting, args.name) if args.caps: output = output.upper() print(output) parser = argparse.ArgumentParser() parser.add_argument('--version', action='version', version='1.0.0') subparsers = parser.add_subparsers() hello_parser = subparsers.add_parser('hello') hello_parser.add_argument('name', help='name of the person to greet') hello_parser.add_argument('--greeting', default='Hello', help='word to use for the greeting') hello_parser.add_argument('--caps', action='store_true', help='uppercase the output') hello_parser.set_defaults(func=greet) goodbye_parser = subparsers.add_parser('goodbye') goodbye_parser.add_argument('name', help='name of the person to greet') goodbye_parser.add_argument('--greeting', default='Hello', help='word to use for the greeting') goodbye_parser.add_argument('--caps', action='store_true', help='uppercase the output') goodbye_parser.set_defaults(func=greet) if __name__ == '__main__': args = parser.parse_args() args.func(args)
Docopt
"""usage: greet [--help] <command> [<args>...] options: -h --help Show this screen. --version Show the version. commands: hello Say hello goodbye Say goodbye """ from docopt import docopt from schema import Schema, SchemaError, Optional HELLO = """usage: basic.py hello [options] [<name>] -h --help Show this screen. --caps Uppercase the output. --greeting=<str> Greeting to use [default: Hello]. """ GOODBYE = """usage: basic.py goodbye [options] [<name>] -h --help Show this screen. --caps Uppercase the output. --greeting=<str> Greeting to use [default: Goodbye]. """ def greet(args): output = '{0}, {1}!'.format(args['--greeting'], args['<name>']) if args['--caps']: output = output.upper() print(output) if __name__ == '__main__': arguments = docopt(__doc__, options_first=True, version='1.0.0') schema = Schema({ Optional('hello'): bool, Optional('goodbye'): bool, '<name>': str, Optional('--caps'): bool, Optional('--help'): bool, Optional('--greeting'): str }) def validate(args): try: args = schema.validate(args) return args except SchemaError as e: exit(e) if arguments['<command>'] == 'hello': greet(validate(docopt(HELLO))) elif arguments['<command>'] == 'goodbye': greet(validate(docopt(GOODBYE))) else: exit("{0} is not a command. See 'options.py --help'.".format(arguments['<command>']))
Click
import click CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help']) def greeter(**kwargs): output = '{0}, {1}!'.format(kwargs['greeting'], kwargs['name']) if kwargs['caps']: output = output.upper() print(output) @click.group(context_settings=CONTEXT_SETTINGS) @click.version_option(version='1.0.0') def greet(): pass @greet.command() @click.argument('name') @click.option('--greeting', default='Hello', help='word to use for the greeting') @click.option('--caps', is_flag=True, help='uppercase the output') def hello(**kwargs): greeter(**kwargs) @greet.command() @click.argument('name') @click.option('--greeting', default='Goodbye', help='word to use for the greeting') @click.option('--caps', is_flag=True, help='uppercase the output') def goodbye(**kwargs): greeter(**kwargs) if __name__ == '__main__': greet()
Invoke
from invoke import task def greet(name, greeting, caps): output = '{0}, {1}!'.format(greeting, name) if caps: output = output.upper() print(output) HELP = { 'name': 'name of the person to greet', 'greeting': 'word to use for the greeting', 'caps': 'uppercase the output' } def print_version(): print('1.0.0') exit(0) @task(help=HELP) def hello(name='', greeting='Hello', caps=False, version=False): """ Say hello. """ if version: print_version() greet(name, greeting, caps) @task(help=HELP) def goodbye(name='', greeting='Goodbye', caps=False, version=False): """ Say goodbye. """ if version: print_version() greet(name, greeting, caps)
錯誤處理一般有三種情況:
1、參數不足。
2、無效的選項/標誌。
3、需要標誌給一個值。
Argparse
$ python argparse/final.py hello usage: final.py hello [-h] [--greeting GREETING] [--caps] name final.py hello: error: the following arguments are required: name $ python argparse/final.py --badoption hello Kyle usage: final.py [-h] [--version] {hello,goodbye} ... final.py: error: unrecognized arguments: --badoption $ python argparse/final.py hello --caps=notanoption Kyle usage: final.py hello [-h] [--greeting GREETING] [--caps] name final.py hello: error: argument --caps: ignored explicit argument 'notanoption'
Docopt,需借助於scheme
... from schema import Schema, SchemaError, Optional ... schema = Schema({ Optional('hello'): bool, Optional('goodbye'): bool, '<name>': str, Optional('--caps'): bool, Optional('--help'): bool, Optional('--greeting'): str }) def validate(args): try: args = schema.validate(args) return args except SchemaError as e: exit(e) if arguments['<command>'] == 'hello': greet(validate(docopt(HELLO))) elif arguments['<command>'] == 'goodbye': greet(validate(docopt(GOODBYE))) ... $ python docopt/validation.py hello None should be instance of <class 'str'> $ python docopt/validation.py hello --greeting Kyle None should be instance of <class 'str'> $ python docopt/validation.py hello --caps=notanoption Kyle --caps must not have an argument usage: basic.py hello [options] [<name>]
Click
$ python click/final.py hello Usage: final.py hello [OPTIONS] NAME Error: Missing argument "name". $ python click/final.py hello --badoption Kyle Error: no such option: --badoption $ python click/final.py hello --caps=notanoption Kyle Error: --caps option does not take a value
打包
entry_point本質上是一個到代碼單一函數的映射,系統PATH將給出一個命令。entry_point的形式是command = package.module:function
包裝click命令
greeter/ ├── greet │ ├── __init__.py │ └── cli.py <-- the same as our final.py └── setup.py
entry_points={ 'console_scripts': [ 'greet=greet.cli:greet', # command=package.module:function ], },
當用戶安裝entry_point創建的包時,setuptools將創建以下可執行腳本(調用greet)並放置它在用戶系統的PATH。
#!/usr/bin/python if __name__ == '__main__': import sys from greet.cli import greet sys.exit(greet())
包裝Argparse命令
代碼:
if __name__ == '__main__': args = parser.parse_args() args.func(args)
變成:
def greet(): args = parser.parse_args() args.func(args) if __name__ == '__main__': greet()
針對entry_point,現在我們可以使用click中定義的相同的模式了。
包裝Docopt命令
代碼:
if __name__ == '__main__': arguments = docopt(__doc__, options_first=True, version='1.0.0') if arguments['<command>'] == 'hello': greet(docopt(HELLO)) elif arguments['<command>'] == 'goodbye': greet(docopt(GOODBYE)) else: exit("{0} is not a command. See 'options.py --help'.".format(arguments['<command>']))
變成:
def greet(): arguments = docopt(__doc__, options_first=True, version='1.0.0') if arguments['<command>'] == 'hello': greet(docopt(HELLO)) elif arguments['<command>'] == 'goodbye': greet(docopt(GOODBYE)) else: exit("{0} is not a command. See 'options.py --help'.".format(arguments['<command>'])) if __name__ == '__main__': greet()
Python命令行解析庫——argarse、docopt、click、invoke