运用场景
- 给原本的service-client项目添加一个本地运行版本。
这里就用到了python的argparse了。argparse是一个处理命令行参数的库,默认是sys.argv[1],详情点这里。
这篇文章只给出在项目中用到的模块:
1.parser
# parser
parser = argparse.ArgumentParser()
cluster_id_opt = argparse.ArgumentParser(add_help=False)
cluster_id_opt.add_argument(
'-c',
'--cluster-id',
type=int,
required=True,
help='the cluster id',
)
parser = argparse.ArgumentParser()
: 创建一个parser对象cluster_id_opt = argparse.ArgumentParser(add_help=False)
: 创建一个id的对象,注意,此时这个对象是全局的(也就是在继承它的子命令下也可以使用,下面会提到)cluster_id_opt.add_argument()
: 给id对象添加参数,可添加多个,这里给的是cluster的id
运行程序时可写成python demo.py -c xxx
2. subparsers
# subparsers
pp = parser.add_subparsers()
parser_create = pp.add_parser(
'create',
parents=[cluster_id_opt],
help='create a new cluster',
)
parser_create.add_argument(
'--name',
type=str,
default='cluster-name',
help='the name of the cluster',
)
parser_create.add_argument(
'-f',
'--file',
action=YamlInputAction,
required=True,
dest='cluster_spec',
help='description options',
)
parser_create.set_defaults(func=transform.setup)
pp = parser.add_subparsers()
: 给parser对象一个子对象parser_create.add_argument()
: 给子对象添加参数,可添加多个,这里的parents
就是上文提到的继承id了,在这个选项里填写对应需要继承的对象名就可以继承该参数parser_create.set_defaults(func=transform.setup)
: 给这个parser_create参数映射到对应的逻辑方法内。
这里有个特殊的地方,那就是这个action
: action原本的方法是不写参数时提供默认值,且默认值是个bool类型
eg:
parser.add_argument('-c', action='store_true', default=false)
python demo.py -c => c是true(因为action)
python demo.py => c是false(default)
但是在这里我们的需求是要解析一个yaml文件,所以我们需要继承argparse.Action,把它改动一下:
class YamlInputAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if os.path.exists(values):
try:
with open(values) as fp:
raw = fp.read()
except Exception:
raise argparse.ArgumentError(self, 'invalid yaml file')
else:
raw = values
try:
v = yaml.safe_load(raw)
if not isinstance(v, dict):
raise argparse.ArgumentError(
self, 'input file is not a dictionary'
)
setattr(namespace, self.dest, v)
except ValueError:
raise argparse.ArgumentError(self, 'invalid yaml content')
这里的代码很简单,就是在call方法内添加读取yaml文件的方法,并把值返回给dest对象。这样我们就可以在命令行解析yaml文件了。
运行程序时可写成:python demo.py create -f ../../examples/fastone.yaml -c 55
在代码的最后一定要写:args = parser.parse_args()
: 运行你的代码
最后,当然,怎么才能拿到我们的参数呢?
def setup(self, args):
cluster_spec = args.cluster_spec
cluster_id = args.cluster_id
...
只要在obj.set_defaults(func=xxx)对应的xxx函数内添加一个args参数,就可以通过obj.add_parser()内的dest
属性内的参数名取得。
以上!