【问题标题】:Store 15 last values on a file on Python在 Python 上的文件中存储 15 个最后的值
【发布时间】:2013-06-07 04:48:58
【问题描述】:

我需要编写一个程序来接收一个整数并将其存储在一个文件中。当它有 15(或 20,确切的数字无关紧要)时,它将覆盖它写入的第一个。它们可能在同一行,也可能在新行中。 该程序从传感器读取温度,然后我将在带有 php 图表的站点上显示。

我想过可能每半小时写一个值,当它有 15 个值并且有一个新值出现时,它会覆盖最旧的值。

我在保存值时遇到了麻烦,我不知道如何将列表保存为带有新行的字符串,它保存了双新行,我是 python 新手,我真的迷路了。

这不起作用,但它是我想做的“样本”:

import sys
import os

if not( sys.argv[1:] ):
    print "No parameter"
    exit()

# If file doesn't exist, create it and save the value
if not os.path.isfile("tempsHistory"):
    data = open('tempsHistory', 'w+')
    data.write( ''.join( sys.argv[1:] ) + '\n' )
else:
    data = open('tempsHistory', 'a+')
    temps = []
    for line in data:
        temps += line.split('\n')
    if ( len( temps ) < 15 ):
        data.write( '\n'.join( sys.argv[1:] ) + '\n' )
    else:
        #Maximum amount reached, save new, delete oldest
        del temps[ 0 ]
        temps.append( '\n'.join( sys.argv[1:] ) )
        data.truncate( 0 )
        data.write( '\n'.join(str(e) for e in temps) )
data.close( )

我迷失了 ''.join 和 \n 等...我的意思是,我必须使用 join 编写以使列表另存为字符串,而不是使用 [ '', '']。如果我使用'\n'.join,我认为它会节省双倍空间。 提前谢谢!

【问题讨论】:

  • 究竟为什么要写入文件,然后在 15 个值之后覆盖旧值?为什么文件不能无限增长?也许无论你试图完成什么,都可以更简单、更好地解决。正如答案中所建议的,这需要一个数据库。内置的sqlite 非常适合。
  • 我在树莓派上做这个,我不想保存我知道我不会使用的东西。如果我要显示 30 分钟的最后 15 个间隔,我想我应该只保存 15 个值!这是主要原因。

标签: python file list


【解决方案1】:

我认为你想要的是这样的:

import sys 

fileTemps = 'temps'

with open(fileTemps, 'rw') as fd:
    temps = fd.readlines()

if temps.__len__() >= 15:
    temps.pop(0)

temps.append(' '.join(sys.argv[1:]) + '\n')

with open(fileTemps, 'w') as fd:
    for l in temps:
        fd.write(l)

首先打开文件进行阅读。 fd.readlines() 调用将为您提供文件中的行。然后检查大小,如果行数大于 15,则弹出第一个值并附加新行。然后将所有内容写入文件。

在 Python 中,一般来说,当您从文件中读取时(例如,使用 readline())会在结尾处为您提供带有 '\n' 的行,这就是您得到双换行符的原因。

希望这会有所帮助。

【讨论】:

  • 真的很干净,就像我想要的那样工作。非常感谢。
【解决方案2】:

你想要类似的东西

values = open(target_file, "r").read().split("\n")
# ^ this solves your original problem as readline() will keep the \n in returned list items
if len(values) >= 15:
    # keep the values at 15
    values.pop()
values.insert(0, new_value)
# push new value at the start of the list
tmp_fd, tmp_fn = tempfile.mkstemp()
# ^ this part is important
os.write(tmp_fd, "\n".join(values))
os.close(tmp_fd)
shutil.move(tmp_fn, target_file)
# ^ as here, the operation of actual write to the file, your webserver is reading, is atomic
# this is eg. how text editors save files

但无论如何,我建议你考虑使用数据库,无论是 postgresql、redis、sqlite 还是任何你喜欢的东西

【讨论】:

    【解决方案3】:

    您应该尽量不要将在列表中存储数据与在字符串中格式化相混淆。数据不需要"\n"s

    所以只要 temps.append(sys.argv[1:]) 就足够了。

    此外,您不应自行序列化/反序列化数据。看看pickle。这比你自己读/写列表要简单得多。

    【讨论】:

    • 没有。使用泡菜是一个可怕的建议。 Pickle 与实现紧密耦合。你不想使用pickle,除非你很快就会加载序列化的东西,处理它然后忘记它。
    猜你喜欢
    • 1970-01-01
    • 2022-01-11
    • 2022-11-22
    • 1970-01-01
    • 2019-05-04
    • 2018-05-05
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    相关资源
    最近更新 更多