将数据附加到现有的json文件

时间:2016-08-25 13:01:01

标签: python json file-io

我有一个现有的JSON文件并尝试将字符串添加到文件中。但是一旦我写了一个JSON文件,新的行字符就会在JSON文件中消失,并且格式会发生变化。

以下是代码:

#!/usr/bin/python
import json

userinput = raw_input('Enter the name of a file a you want to read: ')
with open(userinput) as json_data:
    s = json_data.read()
    data = json.loads(s)
    print data['classes']
json_data.close()


class_add = raw_input('Enter the name of a class a you want to add: ')
if class_add in data['classes']:
    print "Class %s already exists, doing nothing." % class_add
else:
    data['classes'].append(class_add)
    print json.dumps(data)
    print data['classes']
    with open(userinput, 'w') as json_data:
        json_data.write(json.dumps(data))
    json_data.close()

这里还有一个重要的事情是,JSON文件的格式化。因此,默认情况下,我们将使用以下格式化文件。

# cat test.json
{
    "selinux_mode": "enforcing",
    "cis_manages_auditd_service": true,
    "classes": [ "basic", "admin", "lvm"]
}
#

但是一旦我们添加了这个类,就会变成以下内容。

# cat test.json 
{"cis_manages_auditd_service": true, "classes": [ "basic", "admin", "lvm"], "selinux_mode": "enforcing"}

有没有什么方法可以保持JSON空格和新行字符,而不会改变任何内容。

2 个答案:

答案 0 :(得分:0)

JSON不需要特定的布局,但是对于人类可读性稍差的问题,您可以提供indent=2

import sys
import json

userinput = raw_input('Enter the name of a file a you want to read: ')
with open(userinput) as json_data:
    data = json.load(json_data)
    print(data['classes'])


class_add = raw_input('Enter the name of a class a you want to add: ')
if class_add in data['classes']:
    print("Class {} already exists, doing nothing.".format(class_add))
else:
    data['classes'].append(class_add)
    json.dump(data, sys.stdout, indent=2)
    print(data['classes'])
    with open(userinput, 'w') as json_data:
        json.dump(data, json_data, indent=2)

请注意,如果您使用with语句打开文件,则不应显式关闭它(无论是否存在异常,都会在块结束时完成)。

如果您要写入文件,而不是将JSON作为字符串处理,您也应该避免使用json.dumps(data)并使用json.dump(data, file_pointer)。同样适用于json.loads()json.load()

答案 1 :(得分:0)

您可以将indent参数设置为函数json.dumps()为一个整数,表示要缩进的空格数。

这仍然会将输出格式修改为:

import json

s = '''{
    "selinux_mode": "enforcing",
    "cis_manages_auditd_service": true,
    "classes": [ "basic", "admin", "lvm"]
}'''

data = json.loads(s)

>>> print(json.dumps(data))
{"cis_manages_auditd_service": true, "classes": ["basic", "admin", "lvm"], "selinux_mode": "enforcing"}

>>> print(json.dumps(data, indent=4))
{
    "cis_manages_auditd_service": true, 
    "classes": [
        "basic", 
        "admin", 
        "lvm"
    ], 
    "selinux_mode": "enforcing"
}

原始版本和更新版本之间的区别在于classes列表现在显示在多行中。