转储到json时出现意外格式

时间:2015-01-16 12:46:46

标签: python json

我有一个python程序,可以从少数传感器收集数据。我以字符串形式接收数据,如此{ "hum": 48.61, "ts": 1421409826365, "temp": 27.43 }我想将其保存到.json文件中。所以我做了以下

  • 取出字符串并将其转换为字典
  • 我用json.loads(string)来实现这个目的。
  • 然后我将词典添加到列表中
  • 然后使用json.dump
  • 将列表写入文件

预期结果是带有以下内容的json文件。

[
    {
        "light": 666, 
        "ts": 1421409825703, 
        "clr": {
            "r": 0, 
            "b": 0, 
            "g": 0
        }, 
        "prox": 62
    },

    {
        "hum": 48.61, 
        "ts": 1421409826365, 
        "temp": 27.43
    }
]

包含传感器数据的列表,以,

分隔

我得到的是以下内容。

[
    {
        "light": 666, 
        "ts": 1421409825703, 
        "clr": {
            "r": 0, 
            "b": 0, 
            "g": 0
        }, 
        "prox": 62
    }
][
    {
        "hum": 48.61, 
        "ts": 1421409826365, 
        "temp": 27.43
    }
]

每个传感器数据都会添加到单个列表中,并且不会以逗号分隔。

如何确保将所有内容写入一个列表并以逗号分隔?

这是我的代码。

def write_to_file(string):
    jdata = json.loads(string)
    jlist =[]
    jlist.append(jdata)
    with open("Data.json", "a") as outfile:
        json.dump(jlist,outfile, indent=4)

4 个答案:

答案 0 :(得分:1)

假设您一次只获得一个json字符串且无法在一个循环中构建jlist,那么在收集完所有数据后,您需要将其存储起来进行写入。例如:

class Jlist:
    def __init__(self):
        self._jlist = []

    def add(self, json_string):
        self._jlist.append(json.loads(json_string))

    def write(self, file_path):
        with open(file_path, 'w') as outfile:
            json.dump(self._jlist, outfile, indent=4)

在这种情况下,您需要该类才能在添加的调用之间保留_jlist

答案 1 :(得分:0)

您正在从其他功能调用write_to_file。每次清除jlist并且每次只有一个json构造时,您正在写入该文件。

要解决此问题,您可以:

jlist = []  # make jlist a globally accessible variable

def write_to_file(string):
    jdata = json.loads(string)
    jlist.append(jdata)
    with open("Data.json", "w") as outfile:
        json.dump(jlist,outfile, indent=4)

在您的版本中,每次追加到文件末尾。这就是为什么对json.dump的调用将从写入的最后一个json对象继续的原因,这是一个单项列表(该项是字典)。

不使用全局变量的替代解决方案(感谢指出@bruno),每次都不重新读取文件(IO访问速度很慢)将返回jlist到调用函数:

def write_to_file(string, jlist):
    jdata = json.loads(string)
    jlist.append(jdata)
    with open("Data.json", "w") as outfile:
        json.dump(jlist,outfile, indent=4)
    return jlist

只需确保从调用函数中捕获jlist并将其传回。

答案 2 :(得分:0)

好吧我花了几分钟才搞清楚,但这很明显......对于每个传感器输入,你在追加模式下打开“Data.json”并将一个json列表转储给它,所以结果就是你要求的。

这里的解决方案是重新加载“Data.json”中的现有数据,附加到该列表,并将其写回以删除以前的版本,即:

def write_to_file(string):
    jdata = json.loads(string)
    # XXX you may want to handle the case where the file
    # does not yet exist
    with open("Data.json") as infile:
        jlist = json.load(infile)
    jlist.append(jdata)
    with open("Data.json", "w") as outfile:
        json.dump(jlist,outfile, indent=4)

请注意,此代码不能同时在同一个文件上运行...

答案 3 :(得分:0)

我会说正确的答案是制作列表并将其保存到文件应该由两个单独的函数完成(实际上msw的解决方案,使用类,对我来说真的看起来是最好的选择)。

无论如何,如果你仍然想要一个函数来做这两件事,那么这个(诚然是脏的)解决方案可能会起作用:

def write_to_file(string, clear = False, _jlist = []):
    if clear:
        _jlist[:] = []
    jdata = json.loads(string)
    _jlist.append(jdata)
    with open("Data.json", "w") as outfile:
        json.dump(_jlist, outfile, indent=4)

此处_jlist不是全局的,它包含在函数的范围内,但当您使用clear=True作为参数调用它时,清除。所以记住这样做,当你需要一个新鲜的json时清除列表 我用下划线写了_jlist因为你不应该把它当作参数。它被声明为参数,因为这样列表对象只创建一次,而不是每次调用函数。