在Python中创建缓冲区
我对Python的经验不多,想弄清楚一些关于缓冲区的事情:
我想生成一个列表,里面可以分配一定的“缓冲”空间(具体怎么做我还不太清楚),用来生成一些整数。如果这个“缓冲区”满了,我是不是需要一个清空的命令?或者说,怎么才能清理这个缓冲区,以便继续往里面放东西呢?
这是我的代码示例:
for i in range(0,500):
randoms = random.randint(0,100000)
looplist.append(randoms)
我想要的是在looplist里面,应该算是一个缓冲区吧?如果looplist的最大缓冲空间满了,那它需要清空(这个过程中会有暂停吗?或者会发生什么呢)才能继续往这个列表/缓冲区里生成整数。
第二部分问题:能不能简单解释一下缓冲区在Python中是怎么工作的?或者说,Python的内存管理是不是让我们不需要自己分配缓冲区?(如果我们想的话,还是可以这样做吗?)
如果我的问题范围太广,我会编辑一下,尽量描述得清楚一些。
3 个回答
如果我理解得没错,你是在问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
使用一个队列或列表,当这个队列或列表的大小变得足够大时,就按照先进先出的原则,让最早加入的元素被移除。
在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
可能是一个更快的选择,但它们不是线程安全的。