我尝试从文件中读取JSON,获取值,转换它们并返回写入新文件。
{
"metadata": {
"info": "important info"
},
"timestamp": "2018-04-06T12:19:38.611Z",
"content": {
"id": "1",
"name": "name test",
"objects": [
{
"id": "1",
"url": "http://example.com",
"properties": [
{
"id": "1",
"value": "1"
}
]
}
]
}
}
上面是我从文件中读取的JSON。 下面我附上一个获取值的python程序,创建新的JSON并将其写入文件。
import json
from pprint import pprint
def load_json(file_name):
return json.load(open(file_name))
def get_metadata(json):
return json["metadata"]
def get_timestamp(json):
return json["timestamp"]
def get_content(json):
return json["content"]
def create_json(metadata, timestamp, content):
dct = dict(__metadata=metadata, timestamp=timestamp, content=content)
return json.dumps(dct)
def write_json_to_file(file_name, json_content):
with open(file_name, 'w') as file:
json.dump(json_content, file)
STACK_JSON = 'stack.json';
STACK_OUT_JSON = 'stack-out.json'
if __name__ == '__main__':
json_content = load_json(STACK_JSON)
print("Loaded JSON:")
print(json_content)
metadata = get_metadata(json_content)
print("Metadata:", metadata)
timestamp = get_timestamp(json_content)
print("Timestamp:", timestamp)
content = get_content(json_content)
print("Content:", content)
created_json = create_json(metadata, timestamp, content)
print("\n\n")
print(created_json)
write_json_to_file(STACK_OUT_JSON, created_json)
但问题是创建json是不正确的。最后结果我得到了:
"{\"__metadata\": {\"info\": \"important info\"}, \"timestamp\": \"2018-04-06T12:19:38.611Z\", \"content\": {\"id\": \"1\", \"name\": \"name test\", \"objects\": [{\"id\": \"1\", \"url\": \"http://example.com\", \"properties\": [{\"id\": \"1\", \"value\": \"1\"}]}]}}"
这不是我想要实现的目标。这不是正确的JSON。我错了什么?
答案 0 :(得分:2)
更改write_json_to_file(...)
方法,如下所示:
def write_json_to_file(file_name, json_content):
with open(file_name, 'w') as file:
file.write(json_content)
问题是,当您在脚本末尾调用write_json_to_file(STACK_OUT_JSON, created_json)
时,变量created_json
包含string
- 它是JSON表示在create_json(...)
函数中创建的字典。但在write_json_to_file(file_name, json_content)
内,您正在致电:
json.dump(json_content, file)
您告诉json
模块将变量json_content
(包含string
)的JSON表示写入文件。 string
的JSON表示是用双引号("
)封装的单个值,其中包含的所有双引号都被\
转义。
你想要实现的只是简单地将json_content
变量的值写入文件中,而不是再次将JSON序列化。
答案 1 :(得分:1)
您正在将
dict
转换为json
,然后在将其写入文件之前,您将其再次转换为json
。当您重试将json
转换为json
时,它会为\"
提供"
,因为它会假设您在那里有值。
读取
json
文件,将其转换为dict
并对其执行各种操作是个好主意。只有当您想要打印输出或写入文件或返回输出时,转换为json
,因为json.dump()
是昂贵的,它会增加2ms
(大约)的开销可能看起来不多,但是当您的代码在500 microseconds
中运行时,它几乎是4次。
看到您的代码后,我发现您来自java
背景,而在java
getThis()
或getThat()
是模拟代码的好方法因为我们在classes
中的java
代表我们的代码,所以python
只会导致代码的readability
出现问题PEP 8
{{3 }}。
我已更新以下代码:
import json
def get_contents_from_json(file_path)-> dict:
"""
Reads the contents of the json file into a dict
:param file_path:
:return: A dictionary of all contents in the file.
"""
try:
with open(file_path) as file:
contents = file.read()
return json.loads(contents)
except json.JSONDecodeError:
print('Error while reading json file')
except FileNotFoundError:
print(f'The JSON file was not found at the given path: \n{file_path}')
def write_to_json_file(metadata, timestamp, content, file_path):
"""
Creates a dict of all the data and then writes it into the file
:param metadata: The meta data
:param timestamp: the timestamp
:param content: the content
:param file_path: The file in which json needs to be written
:return: None
"""
output_dict = dict(metadata=metadata, timestamp=timestamp, content=content)
with open(file_path, 'w') as outfile:
json.dump(output_dict, outfile, sort_keys=True, indent=4, ensure_ascii=False)
def main(input_file_path, output_file_path):
# get a dict from the loaded json
data = get_contents_from_json(input_file_path)
# the print() supports multiple args so you don't need multiple print statements
print('JSON:', json.dumps(data), 'Loaded JSON as dict:', data, sep='\n')
try:
# load your data from the dict instead of the methods since it's more pythonic
metadata = data['metadata']
timestamp = data['timestamp']
content = data['content']
# just cumulating your print statements
print("Metadata:", metadata, "Timestamp:", timestamp, "Content:", content, sep='\n')
# write your json to the file.
write_to_json_file(metadata, timestamp, content, output_file_path)
except KeyError:
print('Could not find proper keys to in the provided json')
except TypeError:
print('There is something wrong with the loaded data')
if __name__ == '__main__':
main('stack.json', 'stack-out.json')
Modular
,因此很容易单元测试exceptions