一起使用 Argparse 和 Json

新手上路,请多包涵

我是 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 文件输入值。

JSON 输入文件 -

 {
    "testOwner": "my name",
    "tests": [
        "test1",
        "test2",
        "test3"
    ],

    "testParameters": {
        "test1": {
            "param1": "0",
            "param2": "20",
            "param3" : "True"
        },

        "test2": {
            "param1": "cc"
        }
    }
}

原文由 Raj 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.7k
2 个回答

来自 parse_argsargs 命名空间可以转换为字典:

 argparse_dict = vars(args)

JSON 值也在字典中,例如 json_dict 。您可以将选定的值从一个字典复制到另一个字典,或者进行整体规模更新:

 argparse_dict.update(json_dict)

这样 json_dict 值就会覆盖 argparse 值。

如果你想保留两者,你要么需要有不同的参数(键)名称,要么值必须是列表,你可以追加或扩展。这需要做更多的工作,从在 argparse 中使用正确的 nargs 值开始。


修改后的 parser 产生了一个测试输入:

 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’值。

原文由 hpaulj 发布,翻译遵循 CC BY-SA 3.0 许可协议

事实证明,以下注意事项非常容易

  1. 安装程序使用命令行上的值覆盖配置文件中的值
  2. 如果没有在命令行或设置文件中设置选项,它只使用默认值
  3. 它不检查配置文件中的设置是否有效
import argparse
import json

parser = argparse.ArgumentParser()

parser.add_argument('--save_json',
    help='Save settings to file in json format. Ignored in json file')
parser.add_argument('--load_json',
    help='Load settings from file in json format. Command line options override values in file.')

args = parser.parse_args()

if args.load_json:
    with open(args.load_json, 'rt') as f:
        t_args = argparse.Namespace()
        t_args.__dict__.update(json.load(f))
        args = parser.parse_args(namespace=t_args)

# Optional: support for saving settings into a json file
if args.save_json:
    with open(args.save_json, 'wt') as f:
        json.dump(vars(args), f, indent=4)

原文由 Laughingrice 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题