Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python collections.deque是否可以扩展以构建一个;文件缓冲区;?_Python_Deque - Fatal编程技术网

Python collections.deque是否可以扩展以构建一个;文件缓冲区;?

Python collections.deque是否可以扩展以构建一个;文件缓冲区;?,python,deque,Python,Deque,我想用python构建一个循环文件缓冲区来保存文件名(字符串)。缓冲区应具有以下属性 缓冲区的大小是名称存储在缓冲区中的文件大小之和。缓冲区将具有允许的最大大小 添加新文件时,如果缓冲区大小小于允许的最大大小,则会添加该文件名字符串。否则,将推出最旧的修改文件并添加新文件。如果新添加的文件比缓冲区中已存在的所有文件都旧,则不会发生任何事情 是否可以为此目的扩展deque 还是我应该从头开始写?有什么设计理念可以用于此目的吗 谢谢 suresh好的,我相信Raymond Hettinger对您

我想用python构建一个循环文件缓冲区来保存文件名(字符串)。缓冲区应具有以下属性

  • 缓冲区的大小是名称存储在缓冲区中的文件大小之和。缓冲区将具有允许的最大大小
  • 添加新文件时,如果缓冲区大小小于允许的最大大小,则会添加该文件名字符串。否则,将推出最旧的修改文件并添加新文件。如果新添加的文件比缓冲区中已存在的所有文件都旧,则不会发生任何事情
是否可以为此目的扩展deque

还是我应该从头开始写?有什么设计理念可以用于此目的吗

谢谢


suresh

好的,我相信Raymond Hettinger对您的问题的解释是正确的,您的评论澄清了您关心的不是队列的长度,而是所有文件大小的总和。这更有意义,我很高兴我终于明白了你的意思。考虑到这一点,这里有一个基于
heapq
的简单实现,我相信它满足了您所陈述的所有需求。通过将
put
ting
(时间戳、文件名、文件大小)
元组放在队列上使用它,请注意,当您
从队列中获取一个项目时,它将是最旧的文件(即时间戳最小的文件)


请参阅我的编辑历史记录,了解一个完全不同的解决方案,该解决方案涉及次优的
Queue.PriorityQueue
。我忘记了
maxsize
通过阻塞而不是丢弃元素来强制限制。那没什么用

如果我没看错你的问题,你需要一个文件名序列,文件的大小不超过给定的最大值。如果添加的新文件超过最大值,则希望忘记最旧的文件

这个简单的基于deque的类应该很好地处理它:

from collections import deque

class FileDeque(object):
    'FIFO queue of files upto a given total size'

    def __init__(self, maxsize):
        self.maxsize = maxsize
        self.d = deque()
        self.sizes = dict()
        self.currsize = 0

    def append(self, filename, filesize):
        'Add a new file to the FileDeque'
        self.d.append(filename)
        self.sizes[filename] = filesize
        self.currsize += filesize
        while self.currsize > self.maxsize and self.d:
            oldfilename = self.d.popleft()
            oldfilesize = self.sizes.pop(oldfilename)
            self.currsize -= oldfilesize

    def __iter__(self):
        'List files oldest to newest'
        return iter(self.d)
示例会话如下所示:

>>> f = FileDeque(maxsize=10000)
>>> f.append('raptors.txt', 2500)
>>> f.append('rexes.txt', 4200)
>>> list(f)
['raptors.txt', 'rexes.txt']
>>> f.append('stegos.txt', 5000)
>>> list(f)
['rexes.txt', 'stegos.txt']
>>> f.append('brontos.txt', 500)
>>> list(f)
['rexes.txt', 'stegos.txt', 'brontos.txt']
>>> f.append('dactyls.txt', 4000)
>>> list(f)
['stegos.txt', 'brontos.txt', 'dactyls.txt']

deque确实有一个
maxlen
属性,该属性会自动丢弃队列另一端的对象。您是否计划在此列表的生命周期内修改这些文件(即,“最早修改的文件”可能成为“最新修改的文件”)?此外,当您添加一个“比缓冲区中已存在的所有文件都旧”的文件时,是否会减少队列中的文件数,或者干脆忽略该文件?您的意思是最大大小应取决于文件名的长度?文件名的数量?文件名引用的文件的大小?@Darthfett我计划在使用期限内修改这些文件。是的,最老的可以成为最新的。当一个文件已经比所有文件都旧时,我不希望发生任何操作。希望我能澄清。@agf文件名的长度在这里没有作用。大小是文件的大小,文件名指的是。除了他希望它有一个
maxlen
的长度总和,而不是文件名的数量,所以您必须手动实现它。您将得到O(n)个删除,因为
deque
不会按优先级排序。您肯定需要某种队列来完成此任务。@agf,我假设他错误地希望
maxlen
是文件名长度的总和。我无法想象这有什么意义。你的第二点就是我提到的
PriorityQueue
s.Nice edit的原因。你说得对,这真的没有道理。我的新猜测——他指的是文件名所指的文件大小。@agf,谢谢。我开始意识到我误读了原始问题中的“最老的”——他不是指“先进的”,是吗?你的评论现在对我来说更有意义…除非有人需要多线程程序的锁,否则heapq比Queue.PriorityQueue好。除非我认为他不需要FIFO,他需要上次修改时间的最小优先级。
from collections import deque

class FileDeque(object):
    'FIFO queue of files upto a given total size'

    def __init__(self, maxsize):
        self.maxsize = maxsize
        self.d = deque()
        self.sizes = dict()
        self.currsize = 0

    def append(self, filename, filesize):
        'Add a new file to the FileDeque'
        self.d.append(filename)
        self.sizes[filename] = filesize
        self.currsize += filesize
        while self.currsize > self.maxsize and self.d:
            oldfilename = self.d.popleft()
            oldfilesize = self.sizes.pop(oldfilename)
            self.currsize -= oldfilesize

    def __iter__(self):
        'List files oldest to newest'
        return iter(self.d)
>>> f = FileDeque(maxsize=10000)
>>> f.append('raptors.txt', 2500)
>>> f.append('rexes.txt', 4200)
>>> list(f)
['raptors.txt', 'rexes.txt']
>>> f.append('stegos.txt', 5000)
>>> list(f)
['rexes.txt', 'stegos.txt']
>>> f.append('brontos.txt', 500)
>>> list(f)
['rexes.txt', 'stegos.txt', 'brontos.txt']
>>> f.append('dactyls.txt', 4000)
>>> list(f)
['stegos.txt', 'brontos.txt', 'dactyls.txt']