【问题标题】:Parsing input from a json file in Python在 Python 中解析来自 json 文件的输入
【发布时间】:2018-08-23 10:56:10
【问题描述】:

我是 python 新手,正在寻求帮助,我有一个 json 文件 (input.json),我计划将其用作我的 python(版本 2.7.8)脚本的输入文件。

{
  "esxIP": "xx.xx.xx.xx",
  "esxUser": "username",
  "esxPass": "password",
  "vm": {
    "vm1": [
      {
        "ip": "xx.xx.xx.xx",
        "user": "username",
        "pass": "password"
      },
      {
        "device": "naa.axxxxxx1",
        "vmfsType": "vmfs5",
        "diskType": "thin"
      },
      {
        "device": "naa.axxxxxx2",
        "vmfsType": "vmfs6",
        "diskType": "thick"
      }
    ],
    "vm2": [
      {
        "ip": "xx.xx.xx.xx",
        "user": "username",
        "pass": "password"
      },
      {
        "device": "naa.bxxxxxx1",
        "vmfsType": "vmfs5",
        "diskType": "thin"
      },
      {
        "device": "naa.bxxxxxx2",
        "vmfsType": "vmfs6",
        "diskType": "thick"
      }
    ],
    "vm3": [
      {
        "ip": "xx.xx.xx.xx",
        "user": "username",
        "pass": "password"
      },
      {
        "device": "naa.cxxxxxx1",
        "vmfsType": "vmfs5",
        "diskType": "thin"
      },
      {
        "device": "naa.cxxxxxx2",
        "vmfsType": "vmfs6",
        "diskType": "thick"
      }
    ]
  }
}

使用下面的 python 代码,当我知道某个键时,我可以获取该键的值。例如

import json

with open('input.json') as f:
    jInput = json.load(f)
print jInput["vm"]["vm1"][1]["vmfsType"]

这里我在最后一个打印语句中将 VM 名称提供为“vm1”,它正在为第一个设备打印 vmfsType 值:

vmfs5

所以这是我的查询:

  1. 在我的情况下,我无法硬编码 VM 名称,例如vm1、vm2 等,因为它不是静态的。每次都可以更改此输入,甚至有时可能有 2 个 vm,有时可能有 4 个 vm。因此,在代码中,我如何才能一一获取 VM 名称并使用它的关联键运行特定命令,例如

    “vm1”:[ { "ip": "xx.xx.xx.xx", “用户”:“用户名”, “通过”:“密码” }, { “设备”:“naa.axxxxxx1”, "vmfsType": "vmfs5", “磁盘类型”:“薄” }, { “设备”:“naa.axxxxxx2”, "vmfsType": "vmfs6", “磁盘类型”:“厚” } ],

  2. 同样的方式,它们将为每个 VM 提供多个设备,但具有相同的键名,我们如何将它们一一获取并使用它为特定 VM 运行命令。

感谢您的帮助。

谢谢。

【问题讨论】:

标签: python json python-2.7


【解决方案1】:

你的意思是这样的?

for vm_name, vm_data in jInput["vm"].items():
    print("workon on vm {}".format(vm_name)
    # cnx is the {"ip": ... etc} dict (first object in the list). 
    # devices is the list of {"device": ....} dicts
    cnx, devices = vm_data[0], vm_data[1:]
    for device in devices:
        do_something_with(cnx, device)

通过for 循环对序列进行迭代 - for item in sequence: use(item) - 其中item 将被分配序列中的第一个、第二个、第三个等项。对于列表,这非常简单。对于 dicts(也是序列),默认是对键进行迭代,但您可以使用 dict.items() 同时拥有键和值,在这种情况下,每次迭代都会得到一个 (key, value) 元组。然后,您可以使用解包将每个变量分配给不同的迭代变量(即for key, value in dict.items(): ...)。

如果你希望用 Python 做任何严肃的事情,你真的需要学习如何迭代不同的序列类型以及如何使用 dicts。

【讨论】:

    【解决方案2】:

    如果我正确理解您的问题,因为您的 vms 将是一个模式,我会使用一个简单的正则表达式来匹配键模式 -

    import re
    vm_pattern = r"^vm\d+"
    
    for k, v in x["vm"]:
        if re.match(ptrn, k):
            # this will match patterns like vm1, vm12 etc
    

    现在要访问device 以获得一个虚拟机,像这样继续上面的循环 -

    # continuing the above code
    for dictionary in v[0]:
        try:
            device = dictionary['device']
        except KeyError:
            pass
    

    【讨论】:

      【解决方案3】:
      1. 使用 jInput["vm"] 中的键动态获取虚拟机名称:

        with open('test.json') as f:
            jInput = json.load(f)
        
        for k in (jInput["vm"].keys()):
            print k, " /", jInput["vm"][k][1]["vmfsType"]
        
      2. 而不是:

        "vm3": [
            {
                "ip": "xx.xx.xx.xx",
                "user": "username",
                "pass": "password"
            },
            {
                "device": "naa.cxxxxxx1",
                "vmfsType": "vmfs5",
                "diskType": "thin"
            },
            {
                "device": "naa.cxxxxxx2",
                "vmfsType": "vmfs6",
                "diskType": "thick"
            }
        ]
        

      考虑拥有:

          "vm3": [
              {
                  "ip": "xx.xx.xx.xx",
                  "user": "username",
                  "pass": "password"
              },
              {
                  "devices": {
                      "device1": {
                          "id": "naa.cxxxxxx1",
                          "vmfsType": "vmfs5",
                          "diskType": "thin"
                      },
                      "device2": {
                          "id": "naa.cxxxxxx2",
                          "vmfsType": "vmfs6",
                          "diskType": "thick"
                     }
              }
          ]
      

      对 jInput["vm"][k][1]["devices"].keys() 使用相同的方法

      【讨论】:

        猜你喜欢
        • 2022-07-21
        • 1970-01-01
        • 1970-01-01
        • 2015-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-01
        • 1970-01-01
        相关资源
        最近更新 更多