创建符合python中特定JSON的JSON对象

创建符合python中特定JSON的JSON对象,python,json,Python,Json,所以我要做的是使用预先存在的文件在python中对JSON对象进行反向工程。文件内容如下所示: [ { "id": "PA_vnf", "name": "PA", "short-name": "PA", "description": "A firewall PaloAlto", "version": "1.0", "connection-point": [ { "type": "VPORT",

所以我要做的是使用预先存在的文件在python中对JSON对象进行反向工程。文件内容如下所示:

[
{
    "id": "PA_vnf",
    "name": "PA",
    "short-name": "PA",
    "description": "A firewall PaloAlto",
    "version": "1.0",
    "connection-point": [
        {
            "type": "VPORT",
            "name": "PA/cp0"
        },
        {
            "type": "VPORT",
            "name": "PA/cp1"
        },
        {
            "type": "VPORT",
            "name": "PA/cp2"
        }
    ],
    "vdu": [
        {
            "id": "pa_vdu",
            "external-interface": [
                {
                    "virtual-interface": {
                        "type": "VIRTIO"
                    },
                    "vnfd-connection-point-ref": "PA/cp0",
                    "name": "eth0"
                },
                {
                    "virtual-interface": {
                        "type": "VIRTIO"
                    },
                    "vnfd-connection-point-ref": "PA/cp1",
                    "name": "eth1"
                },
                {
                    "virtual-interface": {
                        "type": "VIRTIO"
                    },
                    "vnfd-connection-point-ref": "PA/cp2",
                    "name": "eth2"
                }
            ],
            "guest-epa": {
                "cpu-pinning-policy": "ANY"
            },
            "name": "vdu-1",
            "vm-flavor": {
                "storage-gb": 40,
                "memory-mb": 4096,
                "vcpu-count": 4
            },
            "image": "paloAlto_RIP"
        }
    ],
    "service-function-chain": "UNAWARE",
    "meta": "important info"
}
]
def create_vnf_new ():
  ginfo = nested_dict(5,list)
  ginfo['description'] = 'A firewall PaloAlto'
  ginfo['name'] = 'PA'
  ginfo['id']= 'PA_vnf'
  ginfo['version'] = '1.0'
  ginfo['service-function-chain'] = 'UNAWARE'
  ginfo['short-name'] = 'PA'
  ginfo['vdu']['id'] = 'pa_vdu'
  ginfo['vdu']['name'] = 'vdu-1'
  ginfo['vdu']['image'] = 'paloAlto_RIP'
  ginfo['vdu']['guest-epa']['cpu-pinning-policy'] =  'ANY'
  ginfo['vdu']['external-interface']['virtual-interface']['type'] = 'VIRTIO'
  ginfo['vdu']['external-interface']['vnfd-connection-point-ref'] = "PA/cp0"
  ginfo['vdu']['external-interface']['name'] = 'eth0'
  ginfo['vdu']['vm-flavor']['storage-gb'] = 20
  ginfo['vdu']['vm-flavor']['memory-mb'] = 1024
  ginfo['vdu']['vm-flavor']['vcpu-count'] = 4
  print(json.dumps(ginfo))

def nested_dict(n, type):
  if n == 1:
    return defaultdict(type)
  else:
    return defaultdict(lambda: nested_dict(n-1, type))
为了简化,现在我正在对所有键的值进行硬编码,示例代码如下所示:

[
{
    "id": "PA_vnf",
    "name": "PA",
    "short-name": "PA",
    "description": "A firewall PaloAlto",
    "version": "1.0",
    "connection-point": [
        {
            "type": "VPORT",
            "name": "PA/cp0"
        },
        {
            "type": "VPORT",
            "name": "PA/cp1"
        },
        {
            "type": "VPORT",
            "name": "PA/cp2"
        }
    ],
    "vdu": [
        {
            "id": "pa_vdu",
            "external-interface": [
                {
                    "virtual-interface": {
                        "type": "VIRTIO"
                    },
                    "vnfd-connection-point-ref": "PA/cp0",
                    "name": "eth0"
                },
                {
                    "virtual-interface": {
                        "type": "VIRTIO"
                    },
                    "vnfd-connection-point-ref": "PA/cp1",
                    "name": "eth1"
                },
                {
                    "virtual-interface": {
                        "type": "VIRTIO"
                    },
                    "vnfd-connection-point-ref": "PA/cp2",
                    "name": "eth2"
                }
            ],
            "guest-epa": {
                "cpu-pinning-policy": "ANY"
            },
            "name": "vdu-1",
            "vm-flavor": {
                "storage-gb": 40,
                "memory-mb": 4096,
                "vcpu-count": 4
            },
            "image": "paloAlto_RIP"
        }
    ],
    "service-function-chain": "UNAWARE",
    "meta": "important info"
}
]
def create_vnf_new ():
  ginfo = nested_dict(5,list)
  ginfo['description'] = 'A firewall PaloAlto'
  ginfo['name'] = 'PA'
  ginfo['id']= 'PA_vnf'
  ginfo['version'] = '1.0'
  ginfo['service-function-chain'] = 'UNAWARE'
  ginfo['short-name'] = 'PA'
  ginfo['vdu']['id'] = 'pa_vdu'
  ginfo['vdu']['name'] = 'vdu-1'
  ginfo['vdu']['image'] = 'paloAlto_RIP'
  ginfo['vdu']['guest-epa']['cpu-pinning-policy'] =  'ANY'
  ginfo['vdu']['external-interface']['virtual-interface']['type'] = 'VIRTIO'
  ginfo['vdu']['external-interface']['vnfd-connection-point-ref'] = "PA/cp0"
  ginfo['vdu']['external-interface']['name'] = 'eth0'
  ginfo['vdu']['vm-flavor']['storage-gb'] = 20
  ginfo['vdu']['vm-flavor']['memory-mb'] = 1024
  ginfo['vdu']['vm-flavor']['vcpu-count'] = 4
  print(json.dumps(ginfo))

def nested_dict(n, type):
  if n == 1:
    return defaultdict(type)
  else:
    return defaultdict(lambda: nested_dict(n-1, type))
我得到以下o/p:

{
"short-name": "PA",
"vdu": {
    "name": "vdu-1",
    "image": "paloAlto_RIP",
    "id": "pa_vdu",
    "external-interface": {
        "virtual-interface": {
            "type": "VIRTIO"
        },
        "vnfd-connection-point-ref": "PA/cp0",
        "name": "eth0"
    },
    "guest-epa": {
        "cpu-pinning-policy": "ANY"
    },
    "vm-flavor": {
        "storage-gb": 20,
        "vcpu-count": 4,
        "memory-mb": 1024
    }
},
"description": "A firewall PaloAlto",
"version": "1.0",
"service-function-chain": "UNAWARE",
"id": "PA_vnf",
"name": "PA"
}
上面的O/p非常好,但我希望某些属性(如“外部接口”)具有多个值,这是我无法做到的。我在字典上尝试了append方法,但它不断向我抛出错误“collections.defaultdict”对象没有属性“append”。 我使用的示例append:ginfo['vdu']['external-interface']['vnfd-connection-point-ref'].append(“value”)

我不确定出了什么问题。另外,我如何获得输出中的第一个方括号,这在我的o/p中是缺失的。我知道它应该是一个数组,但我不确定如何在dictionary对象上应用数组逻辑

如果解释不够清楚,请告诉我,因为我是在大约5个小时没有运气的情况下键入此帮助的。

您不会在字典上“应用数组逻辑”。如果你想要一个数组(即列表),那么就使用一个列表。在原始JSON中,
connection\u point
vdu
都是DICT列表,就像
vdu
中的
external interface
一样

如果您确实仍然希望逐行构建此功能,您可以执行以下操作:

ginfo['vdu'] = []
ginfo['vdu'].append({})
ginfo['vdu'][0]['id'] = 'pa_vdu'

等等。

Python
表现力:

ginfo['vdu'] = []
interfaces = []
interfaces.append({'virtual-interface': {'type': 'VIRTIO'}, 
                   'vnfd-connection-point-ref': 'PA/cp0',
                   'name': 'eth0'})
...
...

ginfo['vdu'].append({'id': 'pa_vdu',
                     'external-interface': interfaces})
使用结构的逆向工程更为明确:

>>> pprint(json.loads(json_string))
[{u'connection-point': [{u'name': u'PA/cp0', u'type': u'VPORT'},
                        {u'name': u'PA/cp1', u'type': u'VPORT'},
                        {u'name': u'PA/cp2', u'type': u'VPORT'}],
  u'description': u'A firewall PaloAlto',
  u'id': u'PA_vnf',
  u'meta': u'important info',
  u'name': u'PA',
  u'service-function-chain': u'UNAWARE',
  u'short-name': u'PA',
  u'vdu': [{u'external-interface': [{u'name': u'eth0',
                                     u'virtual-interface': {u'type': u'VIRTIO'},
                                     u'vnfd-connection-point-ref': u'PA/cp0'},
                                    {u'name': u'eth1',
                                     u'virtual-interface': {u'type': u'VIRTIO'},
                                     u'vnfd-connection-point-ref': u'PA/cp1'},
                                    {u'name': u'eth2',
                                     u'virtual-interface': {u'type': u'VIRTIO'},
                                     u'vnfd-connection-point-ref': u'PA/cp2'}],
            u'guest-epa': {u'cpu-pinning-policy': u'ANY'},
            u'id': u'pa_vdu',
            u'image': u'paloAlto_RIP',
            u'name': u'vdu-1',
            u'vm-flavor': {u'memory-mb': 4096,
                           u'storage-gb': 40,
                           u'vcpu-count': 4}}],
  u'version': u'1.0'}]
谢谢@和@我能够使用这两种解决方案来构建最终代码。我把代码放在下面:

import json
import yaml
import sys
from collections import defaultdict

def nested_dict(n, type):
  if n == 1:
    return defaultdict(type)
  else:
    return defaultdict(lambda: nested_dict(n-1, type))

ginfo = nested_dict(5,list)
ginfo = []
ginfo.append({})
ginfo[0]['description'] = 'A firewall PaloAlto'
ginfo[0]['name'] = 'PA'
ginfo[0]['id']= 'PA_vnf'
ginfo[0]['version'] = '1.0'
ginfo[0]['service-function-chain'] = 'UNAWARE'
ginfo[0]['short-name'] = 'PA'
ginfo[0]['vdu'] = []
interfaces = []
interfaces.append({'virtual-interface': {'type': 'VIRTIO'},
                                   'vnfd-connection-point-ref': 'PA/cp0',
                                   'name': 'eth0'})
interfaces.append({'virtual-interface': {'type': 'VIRTIO'},
                                   'vnfd-connection-point-ref': 'PA/cp1',
                                   'name': 'eth1'})
interfaces.append({'virtual-interface': {'type': 'VIRTIO'},
                                   'vnfd-connection-point-ref': 'PA/cp2',
                                   'name': 'eth2'})
ginfo[0]['vdu'].append({'id': 'pa_vdu',
                 'name': 'vdu-1',
         'image': 'paloAlto_RIP',
                 'guest-epa':{'cpu-pinning-policy': 'ANY'},
                 'external-interface': interfaces,
                 'vm-flavor': {'storage-gb': 40,
                 'memory-mb': 4096,
                 'vcpu-count': 4}})
ginfo[0]['connection-point'] = []
cp =[]
cp.append({'type': 'VPORT',
    'name': 'PA/cp0'})
cp.append({'type': 'VPORT',
    'name': 'PA/cp1'})
cp.append({'type': 'VPORT',
    'name': 'PA/cp2'})
ginfo[0]['connection-point'].append({'connection-point': cp})
print(json.dumps(ginfo))

def nested_dict(n, type):
  if n == 1:
    return defaultdict(type)
  else:
    return defaultdict(lambda: nested_dict(n-1, type))
并喷出以下o/p:

-
“简称”:PA
视频显示器:
- 
名称:“vdu-1”
图片:帕洛阿尔托·瑞普
id:pa_vdu
“外部接口”:
- 
“虚拟接口”:
类型:VIRTIO
“vnfd连接点参考”:“PA/cp0”
姓名:eth0
- 
“虚拟接口”:
类型:VIRTIO
“vnfd连接点参考”:“PA/cp1”
姓名:eth1
- 
“虚拟接口”:
类型:VIRTIO
“vnfd连接点参考”:“PA/cp2”
姓名:eth2
“客人环保署”:
“cpu固定策略”:任何
“vm风味”:
“存储gb”:40
“vcpu计数”:4
“内存mb”:4096
描述:“防火墙PaloAlto”
“连接点”:
- 
“连接点”:
- 
类型:VPORT
名称:“PA/cp0”
- 
类型:VPORT
名称:“PA/cp1”
- 
类型:VPORT
名称:“PA/cp2”
版本:“1.0”
“服务功能链”:不知道
id:PA_vnf
名称:PA

这在技术上是正确的。现在的问题是双引号。我不希望属性使用双引号,但是值可以使用双引号。属性的双引号看起来是随机的。 再次感谢你的帮助。既然原来的问题已经回答了,我就把这个问题标记为已解决