docopt main template
docopt用のメイン関数のテンプレートを作成した。以下のdocoptのライブテンプレートを登録しておくと、コマンドラインパーサーを書くのが全く苦にならなくなるので、行なっとこう。
tf_arg
を追加している。docoptは型チェックがなく、複雑なオプションだとどこのフラグの設定が間違っているのかがわかりにくいので、エラーメッセージにフラグの情報を追加する物だ。
コピペとpycharmのlive template用のものを作成した。
for copy and paste
#! /usr/bin/env python3 # encoding: utf-8 """{f}\n Usage: {f} {f} <str> <int> <path> <list>... {f} -h | --help Options: <str> str arg <int> int arg <path> path arg -h --help Show this screen and exit. """ from docopt import docopt from pathlib import Path from typing import TypeVar class DocArgs: A = TypeVar("A", str, Path, int, float, bool, list) def __init__(self, argd: dict): self.argd = argd def __call__(self, value_type: A, flag: str) -> A: """ transformer from docopt option string to another class :param value_type: ex) int, float32, etc :param flag: :return: """ try: print(f" v is {flag}") print(value_type, type(value_type(self.argd[flag]))) arg = value_type(self.argd[flag]) if isinstance(arg, list): inner_type = value_type.__args__[0] arg = [inner_type(z) for z in arg] return arg except ValueError as e: print("check your args") raise e def __str__(self) -> str: return self.argd.__str__() if __name__ == "__main__": args = DocArgs(docopt(__doc__.format(f=__file__, version='0.0.1'))) print(args) arg_str = args(str, "<str>") arg_int = args(int, "<int>") arg_path = args(Path, "<path>") arg_list = args(list[int], "<list>") print(arg_str) print(arg_int) print(arg_path) print(arg_list)
pycharm live template
#! /usr/bin/env python3 # encoding: utf-8 """{f}\n $DISCRIPTION$ Usage: {f} {f} -h | --help Options: -h --help Show this screen and exit. """ from docopt import docopt from pathlib import Path from typing import TypeVar class DocArgs: A = TypeVar("A", str, Path, int, float, bool, list) def __init__(self, argd: dict): self.argd = argd def __call__(self, value_type: A, flag: str) -> A: """ transformer from docopt option string to another class :param value_type: ex) int, float32, etc :param flag: :return: """ try: print(f" v is {flag}") print(value_type, type(value_type(self.argd[flag]))) arg = value_type(self.argd[flag]) if isinstance(arg, list): inner_type = value_type.__args__[0] arg = [inner_type(z) for z in arg] return arg except ValueError as e: print("check your args") raise e def __str__(self) -> str: return self.argd.__str__() if __name__ == "__main__": args = DocArgs(docopt(__doc__.format(f=__file__, version='0.0.1')))