我正在摆弄输出一个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": ""}
答案 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
,尽管您可能希望编写更具内存效率的实现。)然而,值得考虑你正在尝试做什么。实际上, 的单独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)