views:

268

answers:

1

I have a queue (from the Queue module), and I want to get indexed access into it. (i.e., being able to ask for item number four in the queue, without removing it from the queue.)

I saw that a queue uses a deque internally, and deque has indexed access. The question is, how can I use the deque without (1) messing up the queue, (2) breaking thread-safety.

+4  A: 
import Queue

class IndexableQueue(Queue):
  def __getitem__(self, index):
    with self.mutex:
      return self.queue[index]

It's of course crucial to release the mutex whether the indexing succeeds or raises an IndexError, and I'm using a with statement for that. In older Python versions, try/finally would be used to the same effect.

Alex Martelli
So clean... I'm messing up with threads in Java now, and it's not that funny.
e-satis
great answer. Unfortunately, it isn't documented anywhere that Queue is suitable (and even meant, as you say) to be subclassed with access to its internal members. Their being "public" is the only clue. Not even in the source code of the Queue.py module does it say it explicitly, and this is a shame. Your snippet of code in this answer should be an example in the standard lib documentation of Queue, IMHO
Eli Bendersky
@eliben, you're right that the docs of Queue.py's internals is (and has long been) woefully inefficient, but at least it's getting a bit better... e.g. at the time we documented its subclassability (recipe 9.3 in the 2nd ed. of the Cookbook) that wasn't in the docs either, now at least a couple of useful subclasses are supplied...;-).
Alex Martelli
@Alex Martelli: I noticed that the mutex is a Lock, not an RLock. Do you think there's a good reason for this? If it was an RLock I could have assured no one was touching the queue during my entire session of accessing it. What do you think?
cool-RR
Alex Martelli