Python 同时使用Argparse和Json
我是Python的初学者 我想知道Argparse和JSON是否可以一起使用。 比如说,我有变量Python 同时使用Argparse和Json,python,json,argparse,Python,Json,Argparse,我是Python的初学者 我想知道Argparse和JSON是否可以一起使用。 比如说,我有变量p,q,r 我可以将它们添加到argparse中,作为- parser.add_argument('-p','--param1',help='x variable', required=True) parser.add_argument('-q','--param2',help='y variable', required=True) parser.add_argument('-r','--param
p,q,r
我可以将它们添加到argparse中,作为-
parser.add_argument('-p','--param1',help='x variable', required=True)
parser.add_argument('-q','--param2',help='y variable', required=True)
parser.add_argument('-r','--param3',help='z variable', required=True)
现在假设我想从JSON文件中读取相同的变量,可以吗?
因此,我可以从命令行或JSON文件中输入值
d = {"-x": "12", "-y": "42"}
args = []
for item in d.items():
args.extend(item)
parser.parse_args(args)
>>> Namespace(xvar='12', yvar='42')
JSON输入文件-
{
"testOwner": "my name",
"tests": [
"test1",
"test2",
"test3"
],
"testParameters": {
"test1": {
"param1": "0",
"param2": "20",
"param3" : "True"
},
"test2": {
"param1": "cc"
}
}
}
假设您的JSON文件包含以下格式的dict:
d = {"name": ["-x", "--xvar"], "help": "Help message", "required": True}
创建解析器后,您可以像这样“解包”dict:
parser = argparse.ArgumentParser()
parser.add_argument(*(d.pop("name")), **d)
# Put the 'name' as name/flag and then unpack the rest of
# the dict as the rest of the arguments
parser.parse_args("--xvar 12".split())
>>> Namespace(xvar='12')
但是,这会迫使您维护dict键以适应方法的参数名称add_arguments
。您也没有简单/直接的方法来使用更高级的行为,例如使用操作
,类型
,选项
参数
此外,您还必须更改dict的形式,以包含要使用的各种参数。一种解决方案是将name/flag作为元组中dict的键,参数是dict:
d = {("-x", "--xvar"): {"help": "Help message for x", "required": True},
("-y", "--yvar"): {"help": "Help message for y", "required": True}}
for names, args in d.iteritems():
parser.add_argument(*names, **args) # Use a similar unpacking 'magic' as the first example
parser.parse_args("-x 12 --yvar 42".split())
>>> Namespace(xvar='12', yvar='42')
编辑
根据OP的评论,他似乎想解析取自JSON文件的值
d = {"-x": "12", "-y": "42"}
args = []
for item in d.items():
args.extend(item)
parser.parse_args(args)
>>> Namespace(xvar='12', yvar='42')
编辑2
查看
argparse
文档可能有点相关。可以将parse\u args
中的args
命名空间转换为具有以下功能的词典:
argparse_dict = vars(args)
JSON值也在字典中,比如JSON\u dict
。您可以将选定的值从一个字典复制到另一个字典,或执行全比例更新:
argparse_dict.update(json_dict)
这样,json\u dict
值就会覆盖argparse值
如果要同时保留这两个参数,则需要使用不同的参数(键)名称,或者值必须是列表,可以附加或扩展列表。这需要更多的工作,首先在argparse
中使用正确的nargs
值
修改后的
解析器
使用测试输入生成:
In [292]: args=parser.parse_args('-p one -q two -r three'.split())
In [293]: args
Out[293]: Namespace(param1='one', param2='two', param3='three')
In [295]: args_dict = vars(args)
In [296]: args_dict
Out[296]: {'param1': 'one', 'param2': 'two', 'param3': 'three'}
解析JSON字符串(JSON.loads
?)时,会生成一个类似以下的字典:
In [317]: json_dict
Out[317]:
{'testOwner': 'my name',
'testParameters': {'test1': {'param1': '0', 'param2': '20', 'param3': 'True'},
'test2': {'param1': 'cc'}},
'tests': ['test1', 'test2', 'test3']}
我通过将您的显示粘贴到我的Ipython会话中实现了这一点,但我认为JSON加载程序也会产生同样的结果
argparse值可以添加为:
In [318]: json_dict['testParameters']['test3']=args_dict
In [319]: json_dict
Out[319]:
{'testOwner': 'my name',
'testParameters': {'test1': {'param1': '0', 'param2': '20', 'param3': 'True'},
'test2': {'param1': 'cc'},
'test3': {'param1': 'one', 'param2': 'two', 'param3': 'three'}},
'tests': ['test1', 'test2', 'test3']}
在这里,我添加了它作为第三个test
集合,从tests
列表中取了一个名称json_dict['testParameters']['test2']=args_dict
将替换test2
的值
将args值添加到“test2”的未定义值的一种方法是:
In [320]: args_dict1=args_dict.copy()
In [322]: args_dict1.update(json_dict['testParameters']['test2'])
In [324]: json_dict['testParameters']['test2']=args_dict1
In [325]: json_dict
Out[325]:
{'testOwner': 'my name',
'testParameters': {'test1': {'param1': '0', 'param2': '20', 'param3': 'True'},
'test2': {'param1': 'cc', 'param2': 'two', 'param3': 'three'},
'test3': {'param1': 'one', 'param2': 'two', 'param3': 'three'}},
'tests': ['test1', 'test2', 'test3']}
我使用这个版本的
update
来优先考虑JSON字典中的'cc'值。结果非常简单,但需要注意以下几点
import argparse
导入json
parser=argparse.ArgumentParser()
parser.add_参数('--save_json',
help='将设置以json格式保存到文件。在json文件中被忽略')
parser.add_参数('--load_json',
help='以json格式从文件加载设置。命令行选项覆盖文件中的值。')
args=parser.parse_args()
如果args.load_json:
将open(args.load_json,'rt')作为f:
t_args=argparse.Namespace()
参数。命令更新(json.load(f))
args=parser.parse_args(名称空间=t_args)
#可选:支持将设置保存到json文件中
如果args.save_json:
将open(args.save_json,'wt')作为f:
dump(vars(args),f,indent=4)
您是否试图从JSON
设置args,或者使用JSON
指定argsparse
选项?正如我提到的,我想从命令行或JSON输入文件配置一些变量。您必须使用JSON
文件吗<代码>配置通常效果更好,程序的最终结构是什么argsparse
和config
模块只是设置设置的一种方式-您也可以用任何其他方式设置这些设置。因此,关键是我可以通过命令行设置这些参数,或者通过指定要使用的文件,将它们放在文件中。它是否是JSON并不重要,但我认为它使用起来很简单。但是我也有一些结构化的输入,所以我认为JSON更好。在这种情况下,你想看看configparser
它在stdlib()中,如果你需要更多的结构,我个人的偏好是configobj
,你可能正在使用Python 3,它删除了iteritems
方法-如前所述。相反,使用items
方法。实际上,这并不是我想要的。我想知道,我是否可以同时使用命令行或JSON文件为同一组参数指定参数。是否尝试使用命令中参数的值,如果未提供,则使用配置文件中的默认值?在这种情况下,您可以将这些值存储在一个文件中,并将它们与add_argument
的default
参数一起使用。实际上,我应该能够从命令行或文件中输入参数,否则它们将使用默认值。太好了!这正是我想要的。谢谢这就是我一直在寻找的答案!