将Python字典保存到文件,并定期更新

时间:2017-11-08 18:38:31

标签: python json file dictionary

我觉得这是一个非常简单的问题,这里有很多非常相似的问题,但我仍然无法弄清楚如何得到我想要的东西。我正在使用远程设备,我可以在线时连接到它们。我想要一个记录设备最近正常运行时间的文件,如下所示:

# device ID ......... last seen online
{'deviceID1':'Wed Nov 08 2017 06:11:27 PM',
'deviceID2':'Wed Nov 08 2017 06:11:27 PM',
'deviceID3':'Tues Nov 07 2017 03:47:01 PM'}

等。通过将其存储在json文件中并执行json.dumps来存储数据和json.load来查看它,我已经非常接近了。我的代码遵循以下步骤:'ping所有设备ID','检查输出'和'将结果写入文件'。但每次我这样做时,这些值都会被覆盖在线设备,现在不在线。就像在上面一样,我得到的结论是:

# device ID ......... last seen online
{'deviceID1':'Wed Nov 08 2017 06:11:27 PM',
'deviceID2':'Wed Nov 08 2017 06:11:27 PM',
'deviceID3':''}

当我在2017年11月8日星期三06:11:27 PM检查时,deviceID3不在线。但我希望在更新我在线查看的设备的值时保留该值。我怎样才能将这个字典/数据保存在一个文件中,并且每次都为同一组唯一的设备ID更新它?这个question最接近,但是关于附加条目,我想更新已经存在的键的值。感谢。

相关代码:

def write_to_file(data):
    with open(STATUS_FILE, 'w') as file:
        file.write(json.dumps(data))

def create_device_dictionary(deviceIDs):
    devices = {}
    for i in range(0, len(deviceIDs)):
        devices[deviceIDs[i]] = []
    return devices

def check_ping_output(cmd_output_lines,devices):

    for i, line in enumerate(cmd_output_lines):
        device_id = line.strip().strip(':')
        # if the device pinged back...
        if 'did not return' not in cmd_output_lines[i+1]:
            #current UNIX time
            human_readable_time = time.strftime(
                '%a %b %d %Y %I:%M:%S %p',
                time.gmtime(time.time())
            )
            devices[device_id].append(human_readable_time)
        else:
        #    do something here? I want the device ID to be in the file even if it's never appeared online
             pass

    return devices

3 个答案:

答案 0 :(得分:1)

这是我提出的一个基本示例(删除您已经解决过的片段部分,例如时间转换等)

<div class="thumbnail " style="padding:0;">
  <img src="@Umbraco.TypedMedia(item.GetValue<string>(" memberImage ")).Url" class="left" style="width:100%">

  <div class="caption">
    <h4 class="">@item.GetValue("name")</h4>
    <p>@item.GetValue("title")</p>

    @if (item.GetValue("companyLogo") != null) {
    <a href="@item.GetValue(" companyLink ")" target="_blank">
									<img src="@Umbraco.TypedMedia(item.GetValue<string>("companyLogo")).Url" class=" " style=" float:left;">	
								</a> }

    <p class="" style="clear:both">@item.GetValue("bio")</p>

    @*<a href="@item.GetValue(" companyLink ")" class="btn btn-warning pull-right" role="button"><i class="glyphicon glyphicon-edit"></i></a>*@
    <a href="mailto:@item.GetValue(" contactDetails ")">@item.GetValue("contactDetails")</a>

  </div>
</div>

输出:

import json

# Suppose this is your existing json file (I'm keeping it as a string for the sake of the example):
devices_str = '{"deviceIDa":"Wed Nov 08 2017 06:11:27 PM", "deviceIDb":"Wed Nov 08 2017 06:11:27 PM", "deviceIDc":"Tues Nov 07 2017 03:47:01 PM"}'

cmd_output_lines = [
    'deviceIDa:True',
    'deviceIDb:Minion did not return. [No response]',
]
# Generate a dictionary of the devices for current update
devices = dict(
    line.strip().split(':') for line in cmd_output_lines
)
# Filter out the ones currently online, using whatever criteria needed
# In my example, I'm just checking if the response contained a True
online_devices = dict(
    (device_id, resp) for (device_id, resp) in devices.iteritems() if 'True' in resp
#               ^ of course in your case that resp would be current/last seen time
)

# Load existing entries
existing_devices = json.loads(devices_str)

# Update them only overwriting online devices
existing_devices.update(online_devices)

# Final result
print json.dumps(existing_devices)

正如您所看到的,"deviceIDb": "Wed Nov 08 2017 06:11:27 PM", "deviceIDc": "Tues Nov 07 2017 03:47:01 PM", "deviceIDa": "True"} 是唯一已更新的条目(deviceIDa仍然是现有条目中的最后一个条目)

编辑:

更进一步,如果你想记录过去的5个在线时间,你可以使用deviceIDb,或者像这样使用简单的词典:

defaultdict(list)

答案 1 :(得分:0)

我建议您按照以下步骤,而不是将创建的数据直接写入文件:

  1. 阅读上次看到的文件,并将其转换为字典。
  2. 检查字典中的每个deviceID,并更新字典中的值 如果设备在线。
  3. 检查上次查看的字典中没有的任何设备,并将它们的时间戳添加到字典中。
  4. 使用当前修改的字典运行json.dumps的结果替换文件的内容。

答案 2 :(得分:0)

基本上,JSON并不是你想要的好东西。 对于一个 - 你不能只是将新值附加到JSON数据文件,因为它需要关闭结构。

接下来,虽然您可以多次重复使用密钥来构建JSON数据,但是当将其转换为普通的Python dict时,只有最后一个值仍然是可见的(或者如果您将解析器调整好,您将获得异常)。

所以,只是一个普通文件,其中每条记录都是一个新行,想想“CSV” - 对你来说会更好。或者,您可以选择将所有内容移动到SQL DB,例如sqlite。