我想在 python 中构建一个循环文件缓冲区来保存文件名(字符串)。缓冲区应具有以下属性。
是否可以为此目的扩展双端队列?
还是我应该从头开始写?是否有任何设计理念可以用于此目的?
谢谢
肯定的
最佳答案
好的,我相信 Raymond Hettinger 对您的问题的解释是正确的,并且您的评论已阐明您不关心队列的长度,而是关心所有文件大小的总和。这更有意义,我很高兴我终于明白了你的意思。考虑到这一点,这里有一个基于 heapq
的简单实现,我相信它可以满足您提出的所有要求。通过队列上的 put
ting (timestamp, filename, filesize)
元组使用它,并注意当你 get
队列中的一个项目时,它将是最旧的文件(即具有最小时间戳的文件。)
import heapq
class FilenameQueue(object):
def __init__(self, times_sizes_names, maxsize):
self.maxsize = maxsize
self.size = sum(s for t, s, n in times_sizes_names)
self.files = list(times_sizes_names)
heapq.heapify(self.files)
while self.size > self.maxsize:
self.get()
def __len__(self):
return len(self.files)
def put(self, time_size_name):
self.size += time_size_name[1]
if self.size < self.maxsize:
heapq.heappush(self.files, time_size_name)
else:
time_size_name = heapq.heappushpop(self.files, time_size_name)
self.size -= time_size_name[1]
def get(self):
time_size_name = heapq.heappop(self.files)
self.size -= time_size_name[1]
return time_size_name
我添加了一个
__len__
方法,以便您可以在从中获取队列之前对其进行测试。这是一个使用示例:>>> f = FilenameQueue(((22, 33, 'f1'), (44, 55, 'f2'), (33, 22, 'f3')), 150)
>>> while f:
... f.get()
...
(22, 33, 'f1')
(33, 22, 'f3')
(44, 55, 'f2')
>>> f = FilenameQueue(((22, 33, 'f1'), (44, 55, 'f2'), (33, 22, 'f3')), 150)
>>> f.put((55, 66, 'f4'))
>>> while f:
... f.get()
...
(33, 22, 'f3')
(44, 55, 'f2')
(55, 66, 'f4')
请参阅我的编辑历史,了解一个完全不同的解决方案,该解决方案涉及次优的
Queue.PriorityQueue
。我忘记了 maxsize
通过阻塞而不是丢弃元素来强制执行限制。那不是很有用!关于python - 可以扩展 collections.deque 以构建 "file buffer"吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10167839/