[Python-ideas] `__iter__` for queues?
George Sakkis
george.sakkis at gmail.com
Wed Jan 20 21:56:38 CET 2010
On Wed, Jan 20, 2010 at 9:36 PM, Raymond Hettinger
<raymond.hettinger at gmail.com> wrote:
>
> On Jan 20, 2010, at 3:59 AM, cool-RR wrote:
>
> On Wed, Jan 20, 2010 at 7:24 AM, Anh Hai Trinh <anh.hai.trinh at gmail.com>
> wrote:
>>
>> [...]
>>
>> I agree, however, that this should be left out of the stdlib API.
>>
>> --
>> // aht
>
> Okay, but what about having an object like `Queue.dump` (or some other name
> instead of `dump`), which can be iterated? This will be similar to
> `dict.keys` and `dict.values`.
>
> I think you need to abandon the notion of iteration
> and instead focus on your original use case of
> (destructively) pulling all of the items out of a queue.
> Taking a cue (no pun intended) from the DB-API's
> fetchone() and fetchall(), perhaps you're looking for
> a getall() method?
>
> def get_all(self, block=True, timeout=None):
> """Remove and return all items 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 not self._qsize():
> raise Empty
> elif timeout is None:
> while not self._qsize():
> self.not_empty.wait()
> elif timeout < 0:
> raise ValueError("'timeout' must be a positive number")
> else:
> endtime = _time() + timeout
> while not self._qsize():
> remaining = endtime - _time()
> if remaining <= 0.0:
> raise Empty
> self.not_empty.wait(remaining)
> result = []
> while self._qsize():
> result.append(self._get())
> self.not_full.notify()
> return result
> finally:
> self.not_empty.release()
It's not obvious to me what "all" should mean, or even if it makes
sense, in the default case (`block=True, timeout=None`) when there are
no items. IIUC, the implementation above makes it effectively
equivalent to get() in this case, i.e. a list with a single-item is
returned. Although that's reasonable, it seems arbitrary. I'd find
more intuitive a method with signature `get_all(self, timeout=0.0)`,
which by default is equivalent to the `block=False` above, and
equivalent to `block=True, timeout=timeout` if timeout>0.
George
More information about the Python-ideas
mailing list