Python JSON列表解析

1 投票
3 回答
847 浏览
提问于 2025-04-18 17:56

我有一段代码,用来检查一个json配置文件是否存在。如果存在,就加载里面的值;如果不存在,就用用户输入的信息创建一个新的配置文件。

import os
import json

if os.path.isfile("config.json"):
    config = open('config.json', 'r')
    confjson = json.loads(config)
    fruit = confjson['fruit']
    vegetables = confjson['vegetables']

    print "fruit:", fruit
    print "vegetables:", vegetables
else:
    fruit = raw_input("Enter your favourite fruit: ")
    vegetables = raw_input("Enter your favourite vegerables (separated by space): ")
    vegetables = vegetables.split(" ")
    config = open('config.json', 'w')
    config.write('{"fruit":"'+fruit+'","vegetables":'+str(vegetables)+'}')

写入文件的部分运行得很好:

>>> 
Enter your favourite fruit: apple
Enter your favourite vegerables (separated by space): carrot potato
>>> 

但是,当我重新启动程序时,出现了以下错误:

>>> 
Traceback (most recent call last):
  File "C:/Users/dell/Desktop/test2.py", line 6, in <module>
    confjson = json.loads(config)
  File "C:\Python27\lib\json\__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "C:\Python27\lib\json\decoder.py", line 365, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
TypeError: expected string or buffer
>>> 

我还试着把“loads”换成“load”,但也出现了错误:

>>> 
Traceback (most recent call last):
  File "C:/Users/dell/Desktop/test2.py", line 6, in <module>
    confjson = json.load(config)
  File "C:\Python27\lib\json\__init__.py", line 290, in load
    **kw)
  File "C:\Python27\lib\json\__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "C:\Python27\lib\json\decoder.py", line 365, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Python27\lib\json\decoder.py", line 383, in raw_decode
    raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
>>> 

现在,当我把列表换成普通字符串时,一切都正常了。所以问题出在这个蔬菜列表上。那么,我该怎么改才能让它正常工作呢?

3 个回答

1
  1. json.loads 接受的是字符串,而不是 json 文件。
  2. 与其手动格式化一个 json 文件,不如直接把内容写成一个字典,然后保存到文件里。下面是一个简单的示例:

    if os.path.isfile("config.json"):
         config = open('config.json', 'r')
        confjson = json.load(config)
        fruit = confjson['fruit']
        vegetables = confjson['vegetables']    
    
        print "fruit:", fruit
        print "vegetables:", vegetables
    else:
        fruit = raw_input("Enter your favourite fruit: ")
        vegetables = raw_input("Enter your favourite vegerables (separated by space): ")
        vegetables = vegetables.split(" ")
        config = open('config.json', 'w')
        res = {"fruit":fruit,"vegetables":vegetables}
        json.dump(res, config)
        config.close()
    
2

在写代码的时候,你需要把值用双引号包起来。你现在的代码会生成一个像这样的文件:

{"fruit": apple, "vegetables": tomatoes}

这样是不对的,因为“apple”和“tomatoes”也需要加上引号。

我建议你使用 json 这个包来写数据(用 json.dumps),这样可以自动处理字符串中的特殊字符(比如如果用户输入了双引号...)。

在加载数据时,你需要用 json.load,而不是 loads:后者是期待一个字符串作为参数,而前者是从文件(或者类似文件的流对象)中加载 json 数据。

3
  1. 你想从一个文件中加载数据,可以用这个方法:confjson = json.load(config)
  2. 要把字典正确地转换成json格式,可以使用json.dumps(),像这样写:config.write(json.dumps({'fruit': fruit, 'vegetables': vegetables}))

(你方法的问题在于,蔬菜的字符串是单引号,而json格式的字符串应该是双引号)

撰写回答