Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 同时使用Argparse和Json_Python_Json_Argparse - Fatal编程技术网

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

我是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','--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
    参数一起使用。实际上,我应该能够从命令行或文件中输入参数,否则它们将使用默认值。太好了!这正是我想要的。谢谢这就是我一直在寻找的答案!