2017-12-08 8 views
3

json dumpとjson loadを同じデータに使用しました。データはユニコードなので、文字列に変換しました。 ast.literla_evalを使用して、文字列の型を取得しようとしましたが、不正な形式の文字列がエラーになっています。 JSON負荷のast.literal_evalを使用しているときにフォーマットされていない文字列

出力は、私が試した何

('data', u'{\n "a": "spawning", \n "addresses": "", \n "image": "b", \n "OS-EXT-STS:vm_state": "building", \n "c:launched_at": null, \n "d": "e (fgh)", \n "user_id": "hhh", \n 
    "accessIPv4": "", \n "accessIPv6": "", \n "name": "kk", \n "created": "2017-12-08T07:52:44Z", \n "z:xyz": []\n}', <type 'unicode'>) 

下回っているのですか?

 with open('openstack_list.json', 'w') as e: 
      json.dump(check_output(['openstack', 'server', 'show', i, '-f', 'json']), e) 
     with open('openstack_list.json', 'r') as a: 
      data = json.load(a) 
      new_data = data.encode('utf-8') # output type is unicode 
      dict_data = ast.literal_eval(new_data) # output type is string 

私は出力を辞書にしたいが、それは得られない。また、私はnew_data = data.encode('utf-8')が冗長であると信じるように、jsonの負荷はユニコードのデータを与えます。しかし、私が符号化なしでast.literal_evalを使用すると、不正な文字列エラーが発生します。いずれにせよ、私はデータ型を辞書にすることができません。

編集:

エラー:

Traceback (most recent call last): 
    File "openstack_resource_list.py", line 84, in <module> 
    output = get_resources() 
    File "openstack_resource_list.py", line 47, in get_resources 
    dict_data = ast.literal_eval(new_data) 
    File "/usr/lib64/python2.7/ast.py", line 80, in literal_eval 
    return _convert(node_or_string) 
    File "/usr/lib64/python2.7/ast.py", line 63, in _convert 
    in zip(node.keys, node.values)) 
    File "/usr/lib64/python2.7/ast.py", line 62, in <genexpr> 
    return dict((_convert(k), _convert(v)) for k, v 
    File "/usr/lib64/python2.7/ast.py", line 79, in _convert 
    raise ValueError('malformed string') 
ValueError: malformed string 

JSONダンプ前のデータ:check_outputによって返されたデータがすでにJSONですので、あなたがない JSON-IFY必要があることを

"{\n \"aaa\": null, \n \"addresses\": \"inner-net=192.168.0.173, x.x.x.x\", \n \"image\": \"aaa (aaa)\", 
    \n \"aaa:vm_state\": \"active\", \n \"aaa:launched_at\": \"2017-12-08T08:21:45.000000\", \n \"flavor\": \"aaa4 (aaa)\", 
    \n \"id\": \"aaa\", \n \"security_groups\": [\n {\n  \"name\": \"default\"\n }\n ], \n \"user_id\": \"aaa\", 
    \n \"OS-DCF:diskConfig\": \"MANUAL\", \n \"accessIPv4\": \"\", \n \"accessIPv6\": \"\", \n \"progress\": 0, \n \"Oaa:power_state\": 1, \n \"project_id\": \"aaa\", 
    \n \"config_drive\": \"\", \n \"status\": \"ACTIVE\", \n \"updated\": \"2017-12-08T08:21:45Z\", \n \"hostId\": \"aaa\", \n \"OS-SRV-USG:terminated_at\": null, 
    \n \"key_name\": \"pg_ci\", \n \"properties\": \"\", \n \"OS-EXT-AZ:availability_zone\": \"nova\", \n \"name\": \"taaa\", \n \"created\": \"2017-12-08T08:21:31Z\", \n 
    \"os-extended-volumes:volumes_attached\": [\n {\n  \"id\": \"aaa\"\n }\n ]\n}" 
+1

あなたは 'openstack_list.json'の実際の内容を表示できますか?また、Python 2を使用しています。 – poke

+1

あなたのデータが2回jsonifiedされているようです... check_output()のコードまたはcheck_output()の少なくとも生戻り値(_before_ 'json.dump(...) '電話? –

+0

エラースタックトレース –

答えて

3

それは再びjson.dumpである。そのままファイルに書き込むことができ、ファイルは有効なJSONファイルになります。

import json 
from pprint import pprint 

s = """{\n \"aaa\": null, \n \"addresses\": \"inner-net=192.168.0.173, x.x.x.x\", \n \"image\": \"aaa (aaa)\", 
    \n \"aaa:vm_state\": \"active\", \n \"aaa:launched_at\": \"2017-12-08T08:21:45.000000\", \n \"flavor\": \"aaa4 (aaa)\", 
    \n \"id\": \"aaa\", \n \"security_groups\": [\n {\n  \"name\": \"default\"\n }\n ], \n \"user_id\": \"aaa\", 
    \n \"OS-DCF:diskConfig\": \"MANUAL\", \n \"accessIPv4\": \"\", \n \"accessIPv6\": \"\", \n \"progress\": 0, \n \"Oaa:power_state\": 1, \n \"project_id\": \"aaa\", 
    \n \"config_drive\": \"\", \n \"status\": \"ACTIVE\", \n \"updated\": \"2017-12-08T08:21:45Z\", \n \"hostId\": \"aaa\", \n \"OS-SRV-USG:terminated_at\": null, 
    \n \"key_name\": \"pg_ci\", \n \"properties\": \"\", \n \"OS-EXT-AZ:availability_zone\": \"nova\", \n \"name\": \"taaa\", \n \"created\": \"2017-12-08T08:21:31Z\", \n 
    \"os-extended-volumes:volumes_attached\": [\n {\n  \"id\": \"aaa\"\n }\n ]\n}""" 

d = json.loads(s) 
pprint(d) 

出力

{'OS-DCF:diskConfig': 'MANUAL', 
'OS-EXT-AZ:availability_zone': 'nova', 
'OS-SRV-USG:terminated_at': None, 
'Oaa:power_state': 1, 
'aaa': None, 
'aaa:launched_at': '2017-12-08T08:21:45.000000', 
'aaa:vm_state': 'active', 
'accessIPv4': '', 
'accessIPv6': '', 
'addresses': 'inner-net=192.168.0.173, x.x.x.x', 
'config_drive': '', 
'created': '2017-12-08T08:21:31Z', 
'flavor': 'aaa4 (aaa)', 
'hostId': 'aaa', 
'id': 'aaa', 
'image': 'aaa (aaa)', 
'key_name': 'pg_ci', 
'name': 'taaa', 
'os-extended-volumes:volumes_attached': [{'id': 'aaa'}], 
'progress': 0, 
'project_id': 'aaa', 
'properties': '', 
'security_groups': [{'name': 'default'}], 
'status': 'ACTIVE', 
'updated': '2017-12-08T08:21:45Z', 
'user_id': 'aaa'} 

をそして、あなたはクリーンなJSONにそれをしたい場合は、json.dumpまたはjson.dumps

にそのPythonオブジェクトを渡します。そして、あなたは json.loadsでPythonオブジェクトにロードすることができます
print(json.dumps(d, indent=4)) 

出力

{ 
    "aaa": null, 
    "addresses": "inner-net=192.168.0.173, x.x.x.x", 
    "image": "aaa (aaa)", 
    "aaa:vm_state": "active", 
    "aaa:launched_at": "2017-12-08T08:21:45.000000", 
    "flavor": "aaa4 (aaa)", 
    "id": "aaa", 
    "security_groups": [ 
     { 
      "name": "default" 
     } 
    ], 
    "user_id": "aaa", 
    "OS-DCF:diskConfig": "MANUAL", 
    "accessIPv4": "", 
    "accessIPv6": "", 
    "progress": 0, 
    "Oaa:power_state": 1, 
    "project_id": "aaa", 
    "config_drive": "", 
    "status": "ACTIVE", 
    "updated": "2017-12-08T08:21:45Z", 
    "hostId": "aaa", 
    "OS-SRV-USG:terminated_at": null, 
    "key_name": "pg_ci", 
    "properties": "", 
    "OS-EXT-AZ:availability_zone": "nova", 
    "name": "taaa", 
    "created": "2017-12-08T08:21:31Z", 
    "os-extended-volumes:volumes_attached": [ 
     { 
      "id": "aaa" 
     } 
    ] 
} 

オリジナルのJSONでは、キーはアルファベット順にソートされています。クリーンアップされたJSONでこれを行うには、sort_keys=Truejson.dumpsに渡すだけです。

+1

これはそれを行います。 JSONのデータを倍にしないことを学んだ... :) –

関連する問題