Seite 1 von 1

The synchronized Queue from the std lib with a peek method

Verfasst: Donnerstag 7. Februar 2008, 15:37
von Jona
klein aber fein :)

Code: Alles auswählen

"""The synchronized Queue from the standard lib with a peek method"""

import Queue

class PQueue(Queue.Queue):
    
    def peek(self):
        if self._empty():
            raise Queue.Empty
        return self.queue[0]
ich hoffe das ist in ordnung so?
oder muss ich mich hier um die locks kümmern?

Re: The synchronized Queue from the std lib with a peek meth

Verfasst: Donnerstag 7. Februar 2008, 15:51
von EyDu
Jona hat geschrieben:oder muss ich mich hier um die locks kümmern?
Ja!

Aber im Prinzip brauchst du um den Zutriff mit "peek" auch noch einen Schutzt der Queue, da sonst "peek" in den meisten Fällen sinnlos bleiben wird.

Verfasst: Donnerstag 7. Februar 2008, 16:11
von Jona
hmm ja...

man waretet ja eigentlich per queue.get() auf das nächste element.
das muss auch mit queue.peek() gehen.

ich schaus mir nochmal an :)

Verfasst: Donnerstag 7. Februar 2008, 16:48
von Jona

Code: Alles auswählen

"""The synchronized Queue from the standard lib with a peek method"""

import Queue

class PQueue(Queue.Queue):

    def peek(self, block=True, timeout=None):
        """Return but do not remove an item from the queue.

        If optional args 'block' is true and 'timeout' is None (the default),
        block if necessary until an item is available. If 'timeout' is
        a positive number, it blocks at most 'timeout' seconds and raises
        the Empty exception if no item was available within that time.
        Otherwise ('block' is false), return an item if one is immediately
        available, else raise the Empty exception ('timeout' is ignored
        in that case).
        """
        self.not_empty.acquire()
        try:
            if not block:
                if self._empty():
                    raise Empty
            elif timeout is None:
                while self._empty():
                    self.not_empty.wait()
            else:
                if timeout < 0:
                    raise ValueError("'timeout' must be a positive number")
                endtime = _time() + timeout
                while self._empty():
                    remaining = endtime - _time()
                    if remaining <= 0.0:
                        raise Empty
                    self.not_empty.wait(remaining)
            item = self._peek()
            self.not_full.notify()
            return item
        finally:
            self.not_empty.release()
            
    def _peek(self):
        return self.queue[0]
es wird also die kontrolle nach dem lesen des ersten elements wieder abgegeben.
wie bei get().
wenn man also weiss, dass das erste element das richtige ist, stellt man sich wieder an zum poppen.

Code: Alles auswählen

if q.peek() == x:
   return q.get()
das setzt leider vorraus, dass kein anderer dieses element weg nimmt.
alternative wäre die kontrolle nach dem peek nicht abzugeben, aber das widerspricht der philosophie von Queue.

eine andere möglichkeit wäre ein get_if das get nur ausführt wenn eine übergebene expression wahr ist. naja.

jemand ne bessere idee?

Verfasst: Donnerstag 7. Februar 2008, 17:48
von veers
Eine andere Queue für alle Elemente == x verwenden?

Verfasst: Donnerstag 7. Februar 2008, 17:59
von Jona
nein ich möchte einen queue.
das soll eine art bus werden.