get() 是 Python 中从 Queue 移除并返回项的方法。
import queue
q = queue.Queue() # Here
q.put("Apple")
q.put("Orange")
q.put("Banana")
print(q.get())
print(q.get())
print(q.get())
输出:
Apple
Orange
Banana
现在,我想要获取 Queue 中的元素而不将它们移除。
这个能够实现吗?
get() 是 Python 中从 Queue 移除并返回项的方法。
import queue
q = queue.Queue() # Here
q.put("Apple")
q.put("Orange")
q.put("Banana")
print(q.get())
print(q.get())
print(q.get())
输出:
Apple
Orange
Banana
现在,我想要获取 Queue 中的元素而不将它们移除。
这个能够实现吗?
queue_object.queue将返回一个deque对象中的队列副本,您随后可以使用该队列的切片。当然,它与原始队列不同步,但将允许您在复制时查看队列。
为什么您不想这样做有一个很好的解释,在此线程中详细说明:comp.lang.python - Queue peek?。但是,如果您只是想了解Queue如何工作,这是一种简单的方法。
import Queue
q = Queue.Queue()
q.push(1)
q.put('foo')
q.put('bar')
d = q.queue
print(d)
deque(['foo', 'bar'])
print(d[0])
'foo'
-1d
,因为你没有正确回答问题,也没有提到如何删除它,而且这个任务并不适合使用队列互斥锁(正如评论中所述,OP并不需要队列互斥锁)。 - jamylakQueue
对象的 .queue
属性没有前导 _
表示它是私有的,但它是未记录的,因此我不愿使用它。我不会对你的回答进行负面评价,但我认为这不是一个好建议。 - martineau
Queue
模块实现了多生产者、多消费者队列。在线程编程中,当多个线程之间需要安全地交换信息时,它尤其有用。
正如您所见,Queue
模块是专门为了与线程一起使用而创建的,提供的仅有 FIFO、LIFO 和 优先级队列,都没有提供此功能。然而,通过查看 Queue
模块的源代码,可以看到它只是使用了一个collections.deque
(双端队列),它可以轻松完成您的任务。您可以使用常数时间对第一项进行索引 ([0]
) 并使用 .popleft()
方法。
Queue
有一个self.mutex = _threading.Lock()
,但是deque
没有,因此在多线程环境中使用后者而不是前者是不等价的——这里并非如此,因为OP在评论中提到没有使用线程。 - martineau直接访问底层队列是不安全的。
安全的方法是扩展Queue类。如果返回基础的deque对象,则你将得到实时对象而非拷贝。
这样做的结果是,在你迭代期间,它可能会发生更改-如果另一个线程在你迭代期间插入队列,则会导致异常。
Python使用GIL,因此您可以安全地使用list(q.queue)
,因为list()永远不会引起上下文切换。
最好使用与get()函数相同的锁,并且不要对GIL作出假设:
import queue
class SnapshotQueue(queue.Queue):
def snapshot(self):
with self.mutex:
return list(self.queue)
该类可以安全地替代普通队列,并在互斥锁内返回队列状态的快照,而不会影响底层队列操作。
import queue
q = queue.Queue()
q.put("Apple")
q.put("Orange")
q.put("Banana")
print(q.queue[0]) # Here
print(q.queue[1]) # Here
print(q.queue[2]) # Here
print(q.queue) # Here
输出:
Apple
Orange
Banana
deque(['Apple', 'Orange', 'Banana'])
而且,您还可以像下面展示的那样更改队列中的项目:
import queue
q = queue.Queue()
q.put("Apple")
q.put("Orange")
q.put("Banana")
q.queue[0] = "Strawberry" # Here
q.queue[1] = "Lemon" # Here
q.queue[2] = "kiwi" # Here
print(q.queue[0])
print(q.queue[1])
print(q.queue[2])
print(q.queue)
输出:
Strawberry
Lemon
kiwi
deque(['Strawberry', 'Lemon', 'kiwi'])
但是,如果没有put(),你无法向队列中添加元素,如下所示:
import queue
q = queue.Queue()
q.queue[0] = "Apple" # Cannot add
q.queue[1] = "Orange" # Cannot add
q.queue[2] = "Banana" # Cannot add
print(q.queue[0])
print(q.queue[1])
print(q.queue[2])
print(q.queue)
然后,出现了以下错误:
IndexError: deque索引超出范围
collections.deque
,你是否正在使用线程? - jamylak