我正在处理一个辅助项目,并且无法让json
模块解析我存储在文本文件中的json对象。文本文件包含换行符分隔的json对象列表。
到目前为止,我已经确认这个代码正在检索每个完整的json行,然后将其提供给json.loads()
:
def load_save_game(file_name):
save_game = []
with open(file_name) as f:
for line in f.readline():
save_game.append(json.loads(line))
return save_game
当我运行这个时,我会得到一个相当长的回溯:
Traceback (most recent call last):
File ____, line 70, in <module>
main()
File ____, line 66, in main
view = ViewerWindow(load_save_game('played/20_05_2016 16-04-31.txt'))
File ____, line 60, in load_save_game
save_game.append(json.loads(line))
File "C:\Python27\lib\json\__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "C:\Python27\lib\json\decoder.py", line 366, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Python27\lib\json\decoder.py", line 382, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting object: line 1 column 1 (char 0)
我怀疑问题可能与编码有关,但在调查此事后,我发现JSON库可以挑剔诸如真值的大写,悬空逗号和单引号等内容而非双重引号。
Python 2.7似乎使用json的RFC 7159 and ECMA 404规范,所以我使用免费的在线json validator来查看json是否形成错误。它已经成功验证了json的所有标准,因此python应该对输入非常满意。
我托管了json on pastebin的一行,唯一的区别是the file中有没有空格,我也上传了。
我在线寻找解决方案并尝试了一些不同的解决方案,例如大写真值,替换所有单引号,以及解码ascii中的文本。
答案 0 :(得分:3)
您正在循环第一行的字符:
for line in f.readline():
f.readline()
返回一个字符串,即文件的第一行。你根本不需要在这里调用readline()
,只需直接迭代文件对象:
with open(file_name) as f:
for line in f:
if line.strip():
save_game.append(json.loads(line))
我在额外测试中添加了跳过空行(文件末尾可以轻松包含一行)。
您也可以将上述内容转换为列表理解:
def load_save_game(file_name):
with open(file_name) as f:
return [json.loads(l) for l in f if l.strip()]
请注意,如果您的JSON文档本身不包含换行符,则上述仅适用。如果文件中只有一个JSON文档,请使用json.load(f)
(无循环),或使用different technique解析文档中新行的多个JSON文档。
上述方法适用于您提供的示例文件,无论是否有line.strip()
调用:
>>> len(load_save_game(os.path.expanduser('~/Downloads/20_05_2016_16-04-31.txt')))
301
答案 1 :(得分:1)
正如Martijn所提到的,你应该直接迭代打开的文件。
我会写这样的代码:
save_game = map(json.loads, f)
<强> 编辑: 强>
适用于Python2,因为map
会返回list
。如果您使用的是Python3,则需要将map
括在list
。