2017-02-21 2 views
0

これは、既存のファイルを使用してPythonでJSONオブジェクトをリバースエンジニアリングすることです。ファイルの内容は以下の通りである:Pythonの特定のJSONに準拠する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)) 

I 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は完全に罰金ですが、私は「外部インタフェース」のような特定の属性は、私が行うことができないのです複数の値を持つようにしたいです。私は辞書のメソッドを追加しようとしましたが、エラー"'collections.defaultdict'オブジェクトには属性 'append'"がありません。 例:ginfo ['vdu'] ['external-interface'] ['vnfd-connection-point-ref']追加( "値")

何が問題になるのかよく分かりません。また、私はo/pには欠けている出力の最初の大括弧をどのように取得するのですか?私はそれが配列でなければならないことを知っているが、私はどのように私の辞書オブジェクトに配列のロジックを適用するか分からない。

説明が不明確な場合は、約5時間運んでからこのヘルプを入力しているのでお知らせください。

答えて

0

Python表現:json.loadsにのリバースエンジニアリングを使用して

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'}] 
0

辞書に「配列ロジックを適用」しないでください。配列(つまりリスト)が必要な場合は、リストを使用します。オリジナルのJSONでは、connection_pointvduの両方がexternal-interfacevduのように、dictsのリストです。

あなたは本当にまだ行ずつ、これを構築したい場合は、あなたができる:

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

など

0

ありがとうございます@Daniel Rosemanと@klashxx私は両方のソリューションを使用して最終的なコードを作成できました。私はコードの下に入れている:

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を吐き出し:技術的に正しいです

- "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 - "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 "vm-flavor": "storage-gb": 40 "vcpu-count": 4 "memory-mb": 4096 description: "A firewall PaloAlto" "connection-point": - "connection-point": - type: VPORT name: "PA/cp0" - type: VPORT name: "PA/cp1" - type: VPORT name: "PA/cp2" version: "1.0" "service-function-chain": UNAWARE id: PA_vnf name: PA

を。今問題は二重引用符である。属性の二重引用符は必要ありませんが、値の二重引用符は問題ありません。また、二重引用符は属性に対してランダムに表示されます。 助けてくれてありがとう。元の質問に答えられて以来、私はこれを解決しています。

関連する問題