JSON对象与json.dump之间的逗号分隔符

时间:2014-11-05 20:50:37

标签: python json

我正在摆弄输出一个json文件,其中包含目录中文件的一些属性。我的问题是,当附加到文件时,每个对象之间没有分隔符。我可以在每个'f'之后添加一个逗号并删除最后一个,但这对我来说似乎是一个草率的工作。

import os
import os.path
import json

#Create and open file_data.txt and append 
with open('file_data.txt', 'a') as outfile:

    files = os.listdir(os.curdir)


    for f in files:

        extension = os.path.splitext(f)[1][1:]
        base = os.path.splitext(f)[0]
        name = f

        data = {
            "file_name" : name,
            "extension" : extension,
            "base_name" : base
                }

        json.dump(data, outfile)

输出:

{"file_name": "contributors.txt", "base_name": "contributors", "extension": "txt"}{"file_name": "read_files.py", "base_name": "read_files", "extension": "py"}{"file_name": "file_data.txt", "base_name": "file_data", "extension": "txt"}{"file_name": ".git", "base_name": ".git", "extension": ""}

我想要的是实际的JSON:

{"file_name": "contributors.txt", "base_name": "contributors", "extension": "txt"},{"file_name": "read_files.py", "base_name": "read_files", "extension": "py"},{"file_name": "file_data.txt", "base_name": "file_data", "extension": "txt"}{"file_name": ".git", "base_name": ".git", "extension": ""}

2 个答案:

答案 0 :(得分:10)

您获得的不是JSON对象,而是一组独立的JSON对象。

你想要的是仍然不是一个JSON对象,而是一个单独的JSON对象流,它们之间有逗号。那将不再是可以解析的了。*

* JSON spec非常简单,可以手工解析,而且应该非常清楚,一个对象后跟另一个逗号之间的对象并不匹配任何有效的生产。< /子>


如果您正在尝试创建JSON数组,则可以执行此操作。除非存在内存问题,否则显而易见的方法是构建一个dicts列表,然后立即转储所有内容:

output = []
for f in files:
    # ...
    output.append(data)
json.dump(output, outfile)

如果记忆存在问题,您可以选择以下几种方法:

  • 对于快速而肮脏的解决方案,您可以手动编写[,]来伪造它。 (但请注意,在最后一个值之后有一个额外的尾随逗号是无效的JSON,即使某些解码器会接受它。)
  • 您可以将循环包装在生成每个data的生成器函数中,并扩展JSONEncoder以将迭代器转换为数组。 (请注意,这实际上用作the example in the docs为什么以及如何扩展JSONEncoder,尽管您可能希望编写更具内存效率的实现。)
  • 您可以查找具有某种内置迭代流API的第三方JSON库。

然而,值得考虑你正在尝试做什么。实际上, 的单独JSON对象流可能是您正在尝试执行的操作的正确文件格式/协议/ API。因为JSON是自我分隔的,所以没有理由在不同的值之间添加分隔符。 (并且它对稳健性的帮助甚至不大,除非你使用的分隔符不会显示在实际的JSON上,如,那样。)例如,你是什么&# 39;得到的正是JSON-RPC应该是什么样子。如果你因为不知道如何解析这样的文件而只是要求不同的东西,这很容易。例如(为简单起见,使用字符串而不是文件):

i = 0
d = json.JSONDecoder()
while True:
    try:
        obj, i = d.raw_decode(s, i)
    except ValueError:
        return
    yield obj

答案 1 :(得分:-1)

我遇到了同样的问题,因为我不想将整个对象列表加载到内存中,因此需要yield个对象到文件中。 这是我的方法(但我认为这有点怪癖):

json_begin = '{"objects":['
json_end = ']}'

with open('file_data.txt', 'a') as outfile:
   files = os.listdir(os.curdir)

   outfile.write(json_begin)

   for f in files:

       extension = os.path.splitext(f)[1][1:]
       base = os.path.splitext(f)[0]
       name = f

       data = {
           "file_name" : name,
           "extension" : extension,
           "base_name" : base
       }

       json.dump(data, outfile)
       if f != files[-1]:
           outfile.write(',')

   outfile.write(json_end)