如何优雅地加载args命令行参数

  参考资料:

  EveryDream2Trainer代码仓库

  使用Linux写一个python脚本,不可缺少的常客的就是argparse,这个小东西能够高效地解析命令行参数。但是一个经常的情景是命令行参数繁多,如果每次都在python XX.py后面接上一大堆参数,不仅不好看,而且容易出错。今天在EveryDream这个代码仓库看到一个非常优雅的方式,可以作为之后解析命令行参数的准绳!

argparser = argparse.ArgumentParser(description="EveryDream2 Training options")
argparser.add_argument("--config", type=str, required=False, default=None, help="JSON config file to load options from")
args, argv = argparser.parse_known_args()

if args.config is not None:
    print(f"Loading training config from {args.config}.")
    with open(args.config, 'rt') as f:
        args.__dict__.update(json.load(f))
        if len(argv) > 0:
            print(f"Config .json loaded but there are additional CLI arguments -- these will override values in {args.config}.")
else:
    print("No config file specified, using command line args")

  有三个点需要注意:

  1. parse_known_args,由于此处我们只add了config这一个参数,所以除了config之外的命令行参数都会忽略掉。
  2. args, argv = argparser.parse_known_args(),这个函数的返回值,前者应该是一个命名空间,只包括config这一个参数,后者应该是去掉--config之后其他的argv,这个就会用到下面的if判断中去。
  3. args.__dict__.update(json.load(f)),使用json中的项目更新args的命名空间。

  接下来,如果使用命令行参数临时override一些args,应该如何是好:

argparser = argparse.ArgumentParser(description="EveryDream2 Training options")
argparser.add_argument(XXX)
...
# load CLI args to overwrite existing config args
args = argparser.parse_args(args=argv, namespace=args)
print(f" Args:")
pprint.pprint(vars(args))

  有几个点需要注意:

  1. 需要新建一个argparser来处理除了config之外的命令行参数。
  2. parse_args的参数不再留空,而是继承自上一个argparser的返回值,这样就是补全之前的命名空间。
  3. 使用vars加上pprint可以美观地输出args,需要注意在此之前要import pprint
posted @ 2023-05-18 10:57  思念殇千寻  阅读(165)  评论(0编辑  收藏  举报