在Python中创建缓冲区

7 投票
3 回答
22546 浏览
提问于 2025-04-17 13:53

我对Python的经验不多,想弄清楚一些关于缓冲区的事情:

我想生成一个列表,里面可以分配一定的“缓冲”空间(具体怎么做我还不太清楚),用来生成一些整数。如果这个“缓冲区”满了,我是不是需要一个清空的命令?或者说,怎么才能清理这个缓冲区,以便继续往里面放东西呢?

这是我的代码示例:

for i in range(0,500):
    randoms = random.randint(0,100000)
    looplist.append(randoms)

我想要的是在looplist里面,应该算是一个缓冲区吧?如果looplist的最大缓冲空间满了,那它需要清空(这个过程中会有暂停吗?或者会发生什么呢)才能继续往这个列表/缓冲区里生成整数。

第二部分问题:能不能简单解释一下缓冲区在Python中是怎么工作的?或者说,Python的内存管理是不是让我们不需要自己分配缓冲区?(如果我们想的话,还是可以这样做吗?)

如果我的问题范围太广,我会编辑一下,尽量描述得清楚一些。

3 个回答

0

如果我理解得没错,你是在问Python是否会为你管理列表的内存。答案是肯定的,你可以不断往列表里添加东西,Python会根据需要自动扩展这个列表(当然,这也是有个限度的——如果你一直添加,最终会耗尽内存)。

我觉得你可能还想知道如何限制这个增长,以确保你的列表不会超过某个大小。如果是这样的话,你可以看看collections.deque这个东西。

举个例子:

import random
from collections import deque

def test_queue(max_size=10):
    d = deque([], max_size)
    for i in xrange(1, 2*max_size):
        r = random.randint(0, 100000)
        d.append(r)
        print 'i=%d, len=%d r=%d' % (i, len(d), r)

    while d:
        print d.popleft()

上面的函数会确保你创建的deque对象不会超过max_size个元素。如果你往deque里添加更多元素,最早添加的元素会自动被移除。下面是这个函数的一个示例运行:

i=1, len=1 r=83870
i=2, len=2 r=12432
i=3, len=3 r=87084
i=4, len=4 r=3485
i=5, len=5 r=12237
i=6, len=6 r=81401
i=7, len=7 r=24990
i=8, len=8 r=21391
i=9, len=9 r=34153
i=10, len=10 r=63651
i=11, len=10 r=96305
i=12, len=10 r=46671
i=13, len=10 r=19288
i=14, len=10 r=40170
i=15, len=10 r=45399
i=16, len=10 r=94032
i=17, len=10 r=57749
i=18, len=10 r=68440
i=19, len=10 r=59726
63651
96305
46671
19288
40170
45399
94032
57749
68440
59726
1

使用一个队列或列表,当这个队列或列表的大小变得足够大时,就按照先进先出的原则,让最早加入的元素被移除。

4

在Python中,你不需要担心内存管理。你只需要给想用的变量赋值,就可以直接使用它们,不用预留什么“缓冲区”。

不过,如果你分配的变量太多,超过了你的内存(RAM)能承受的范围,就可能会遇到MemoryError,这表示你的内存不够用了。

你可以使用队列(Queue)作为某种缓冲区,比如:

import random
from Queue import Queue, Full

q = Queue(100)

for i in range(10):
    #fill queue
    while True:
        try:
            q.put_nowait(random.randint(1,10))
        except Full:
            break
    #take some values from queue
    print "Round", i,
    number_of_values_to_get = random.randint(0,20)
    print "getting %i values." % number_of_values_to_get
    for j in range(number_of_values_to_get):
        value = q.get()
        print "  got value", value

我创建了一个大小为100的队列,也就是说,最多可以在里面存放100个条目。如果你试图在一个满的队列里再放东西,就会抛出相应的异常,所以最好要处理这个异常。(这只有在你使用put_nowait或者带有超时的put时才会发生,具体可以查看文档了解更多细节。)

在这个例子中,我进行了十轮操作,填充了一个包含100个随机整数的“缓冲区”(队列)。然后,我从这个缓冲区中随机选择0到20个值并打印出来。

希望这对你有帮助。队列的主要用途是在多线程程序中执行,它们是线程安全的。所以你可能会想在一个线程中填充队列,然后在另一个线程中读取它。如果你不需要多线程,collections.deque可能是一个更快的选择,但它们不是线程安全的。

撰写回答