简体   繁体   English

如何在不删除项目的情况下获取队列中的项目?

[英]How to get the items in Queue without removing the items?

get() removes and returns an item from Queue in Python.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())

Output: Output:

Apple
Orange
Banana

Now, I want to get the items in Queue without removing the items.现在,我想在不删除项目的情况下获取队列中的项目。

Is it possible to do this?是否有可能做到这一点?

queue_object.queue will return copy of your queue in a deque object which you can then use the slices of. queue_object.queue 将在 deque 对象中返回队列的副本,然后您可以使用其切片。 It is of course, not syncronized with the original queue, but will allow you to peek at the queue at the time of the copy.当然,它不会与原始队列同步,但可以让您在复制时查看队列。

There's a good rationalization for why you wouldn't want to do this explained in detail in this thread comp.lang.python - Queue peek?有一个很好的理由说明为什么你不想这样做,在这个线程comp.lang.python - Queue peek中有详细解释 . . But if you're just trying to understand how Queue works, this is one simple way.但是,如果您只是想了解 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'

The Queue module implements multi-producer, multi-consumer queues. Queue模块实现了多生产者、多消费者队列。 It is especially useful in threaded programming when information must be exchanged safely between multiple threads.当必须在多个线程之间安全地交换信息时,它在线程编程中特别有用。

As you can see, the Queue module was created specifically for use with threads, providing only FIFO , LIFO and priority queues , none of which provide this functionality.如您所见, Queue模块是专门为与线程一起使用而创建的,仅提供FIFOLIFO优先级队列,它们都没有提供此功能。 However by examining the source code of the Queue module, you can see that it simply uses a collections.deque (double ended queue) which can easily accomplish your task.但是通过查看Queue模块的源代码,您可以看到它只是使用了一个可以轻松完成任务的collections.deque (双端队列)。 You may index the first item ( [0] ) and .popleft() in constant time.您可以在恒定时间内索引第一项 ( [0] ) 和.popleft()

It is NOT safe to simply access the underlying queue.简单地访问底层队列是不安全的。

The safe way to do it is to extend the Queue class.安全的方法是扩展 Queue 类。 If you return the underlying dequeue object, you will NOT be getting a copy, you get the live object .如果您返回底层 dequeue 对象,您将不会获得副本,而是获得活动对象

The result of this is that it can change while you are iterating it - which will result in an exception if another thread inserts into the queue during your iteration.这样做的结果是它可以在您迭代它时更改 - 如果在您的迭代期间另一个线程插入队列中,这将导致异常。

Knowing that python uses the GIL, you can safely use list(q.queue) , because list() will never cause a context switch.知道 python 使用 GIL,您可以安全地使用list(q.queue) ,因为 list() 永远不会导致上下文切换。

It's better to use the same lock the get() function uses, and not make assumptions about the GIL:最好使用与 get() 函数相同的锁,而不是对 GIL 做出假设:

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

That class can be used safely instead of a regular queue, and it will return a snapshot of the queue state... within a mutex and without causing issues in the underlying queue operation.该类可以安全地使用而不是常规队列,并且它将返回队列状态的快照......在互斥锁中并且不会导致底层队列操作出现问题。

I found this question, because I needed a way to access top element in a PriorityQueue.我发现了这个问题,因为我需要一种方法来访问 PriorityQueue 中的顶部元素。 I couldn't find a way to do that, so I switched to heapq instead.我找不到这样做的方法,所以我改用 heapq。 Although it's worth mentioning that heapq is not thread safe.虽然值得一提的是 heapq 不是线程安全的。

You can get the items in a queue without removing the items as shown below:您可以在不删除项目的情况下获取队列中的项目,如下所示:

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

Output: Output:

Apple
Orange
Banana
deque(['Apple', 'Orange', 'Banana'])

And, you can also change the items in a queue as shown below:而且,您还可以更改队列中的项目,如下所示:

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)

Output: Output:

Strawberry
Lemon
kiwi
deque(['Strawberry', 'Lemon', 'kiwi'])

But, you cannot add items to a queue without put() as shown below:但是,您不能在没有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)

Then, the error below occurs:然后,出现以下错误:

IndexError: deque index out of range IndexError:双端队列索引超出范围

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM