如何在不移除Python中的项目的情况下获取Queue中的项目?

8yparm6h  于 2022-11-26  发布在  Python
关注(0)|答案(5)|浏览(313)

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中的项目,但不移除这些项目。
有可能做到这一点吗?

mf98qq94

mf98qq941#

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'
xriantvc

xriantvc2#

Queue模块实现了多生产者、多消费者队列。在多线程编程中,当信息必须在多个线程之间安全交换时,它特别有用。
正如您所看到的,Queue模块是专门为与线程一起使用而创建的,只提供了 FIFOLIFO 和 * 优先级队列 *,它们都不提供此功能。可以看到它只使用了collections.deque(双端队列),可以轻松完成您的任务。您可以在常数时间内索引第一项([0])和.popleft()

v64noz0r

v64noz0r3#

仅访问基础队列是不安全的。

安全的方法是扩展Queue类。如果返回底层的出队对象,您将不会获得副本,* 您将获得活动对象 *。
这样做的结果是,当您迭代它时,它可能会发生变化-如果在迭代过程中另一个线程插入到队列中,这将导致异常。
知道python使用GIL,就可以安全地使用list(q.queue),因为list()永远不会导致上下文切换。
最好使用get()函数使用的同一个锁,而不要对GIL做假设:

import queue
    
class SnapshotQueue(queue.Queue):
    def snapshot(self):
        with self.mutex:
            return list(self.queue)

可以安全地使用该类来代替常规队列,并且它将在互斥体中返回队列状态的快照,而不会导致基础队列操作出现问题。

kzipqqlq

kzipqqlq4#

我发现了这个问题,因为我需要一种方法来访问PriorityQueue中的top元素。我找不到这样做的方法,所以我改用heapq。尽管值得一提的是,heapq不是线程安全的。

trnvg8h3

trnvg8h35#

您可以在不移除项目的情况下获取队列中的项目,如下所示:

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:双队列索引超出范围

相关问题