前一段工作中一个python项目有一个小需求,要通过命令行向程序传递json格式的参数。这里分享一下实现的心得,主要是两部分:
1.使用argparse来获取命令行参数:
argparse是是Python标准库中推荐使用的编写命令行程序的工具
通过一个例子来解释一下argparse的基本使用:
import argparse
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
const=sum, default=max,
help='sum the integers (default: find the max)')
args = parser.parse_args()
设置一个解析器
使用argparse的第一步就是创建一个解析器对象,并告诉它将会有些什么参数。那么当你的程序运行时,该解析器就可以用于处理命令行参数。
解析器类是 ArgumentParser 。构造方法接收几个参数来设置用于程序帮助文本的描述信息以及其他全局的行为或设置。开始的这部分代码就是设置一个解析器:
import argparse
parser = argparse.ArgumentParser(description='Process some integers.')
定义参数
argparse是一个全面的参数处理库。参数可以触发不同的动作,动作由 add_argument() 方法的 action 参数指定。 支持的动作包括保存参数(逐个地,或者作为列表的一部分),当解析到某参数时保存一个常量值(包括对布尔开关真/假值的特殊处理),统计某个参数出现的次数,以及调用一个回调函数。
默认的动作是保存参数值。在这种情况下,如果提供一个类型,那么在存储之前会先把该参数值转换成该类型。如果提供 dest 参数,参数值就保存为命令行参数解析时返回的命名空间对象中名为该 dest 参数值的一个属性。
parser.add_argument('integers', metavar='N', type=int, nargs='+',help='an integer for the accumulator')
解析一个命令行
定义了所有参数之后,你就可以给 parse_args() 传递一组参数字符串来解析命令行。默认情况下,参数是从 sys.argv[1:] 中获取,但你也可以传递自己的参数列表。选项是使用GNU/POSIX语法来处理的,所以在序列中选项和参数值可以混合。
parse_args() 的返回值是一个命名空间,包含传递给命令的参数。该对象将参数保存其属性,因此如果你的参数 dest 是 "myoption",那么你就可以args.myoption 来访问该值。
args = parser.parse_args()
这里是简单的介绍一下如何快速的使用argparse,如果想要查看更详细的使用方法可以查看官方文档
2.向argparse传一个json格式的参数
argparse的文档中说可以支持所有的格式作为参数来传递:
Any object that supports the in operator can be passed as the choices value, so dict objects, set objects, custom containers, etc. are all supported.
但是,但是如果把add_argument设成dict,是会报错的。所以这里的传递任意类型,其实是以str传递,然后再转换成任意的类型。
完成传入json变量的目的的代码:
parser.add_argument('-m', '--my-dict', type=str)
args = parser.parse_args()
import json
my_dictionary = json.loads(args.my_dict)
这样就是先以str来传入参数,然后再再自行转换。当然这样不够便捷。
更方便的方式是改进add_argument的type,直接把type类型变为json转换。代码:
import json
parser.add_argument('-d', '--my-dict', type=json.loads)
args = parse.parse_args()
这样就可以直接传递json的参数了。