我有一个文件,其中不断写入新行。
在python中,我想连续读取这个文件的最后一行,以便我可以处理该行。
我知道有
readlines()
功能,但这是“静态”的。如果在我调用 readlines()
之后添加新行,这些新行将不会被读取。
我怎样才能在Python中做到这一点? 谢谢
您将需要使用“状态机”。这只是一种奇特的表达方式,您想要跟踪您在文件中的位置,因此您可以
seek()
到该位置,read()
到文件末尾,并每次读取并前进当前位置遇到换行符。
你可以使用这样的东西,它也可以像迭代器一样使用:
import time
class LogFollower:
def __init__(self, fp):
self.position = 0
self.fp = fp
def seek(self):
self.fp.seek(self.position)
def has(self):
self.seek()
return '\n' in self.fp.read()
def __iter__(self):
while self.has():
self.seek()
line = self.fp.read().split('\n')[0]
yield line
# advance position - this is the 'state machine' part!
self.position += len(line) + 1
follow = LogFollower(open("my_file.txt"))
# assume the file already has 2 lines
for line in follow:
print(line)
#>foo
#>bar
time.sleep(5)
# now suppose a line 'baz' is added to the bottom
# somewhere during those 10 secs, then you decide
# to iterate again.
for line in follow:
print(line)
#>baz
您还可以通过再次迭代来连续检查新行,如上面的假设示例所示,当附加
baz
时。
请注意,这样,每一行都必须以换行符结束 (
\n
)。这让事情变得更简单,我想这可能就是为什么它是通常的约定的原因。
这个示例采用了稍微更实际的方法,而不仅仅是像
this这样的简单
readline
循环。我认为这样需要更多的行数。然而,我认为出于说明目的它更清晰;我认为它在通过简单的面向对象编程解释任务的基础知识方面做得足够好。
附注我拨打
seek
的次数可能比我真正需要的次数要多。例如,在 has()
中每次运行 for
循环之后,我可以不在 __next__
函数中调用它。不过,为了说明清楚起见,我决定保持这种方式。 :)
P.P.S。我知道这并不是真正的状态机。我的意思是在非常广泛的意义上。实际的有限状态机是一个完全不同的概念。所有这一切都是在每次遇到新行时增加一个计数器。我希望这不会太误导人,而且我试图表达的实际观点仍然很清楚 – 保持跟踪。