Multi thread reading a file

ryles rylesny at gmail.com
Thu Jul 2 22:10:18 EDT 2009


On Jul 2, 6:10 am, "Gabriel Genellina" <gagsl-... at yahoo.com.ar> wrote:
> En Wed, 01 Jul 2009 12:49:31 -0300, Scott David Daniels  
> <Scott.Dani... at acm.org> escribió:
> > These loops work well with the two-argument version of iter,
> > which is easy to forget, but quite useful to have in your bag
> > of tricks:
>
> >      def convert(in_queue, out_queue):
> >          for row in iter(in_queue.get, None):
> >              # ... convert row
> >              out_queue.put(converted_line)
>
> Yep, I always forget about that variant of iter() -- very handy!

Yes, at first glance using iter() here seems quite elegant and clever.
You might even pat yourself on the back, or treat yourself to an ice
cream cone, as I once did. There is one subtle distinction, however.
Please allow me to demonstrate.

>>> import Queue
>>>
>>> queue = Queue.Queue()
>>>
>>> queue.put(1)
>>> queue.put("la la la")
>>> queue.put(None)
>>>
>>> list(iter(queue.get, None))
[1, 'la la la']
>>>
>>> # Cool, it really works! I'm going to change all my old code to use this... new and *improved*
...
>>> # And then one day your user inevitably does something like this.
...
>>> class A(object):
...     def __init__(self, value):
...         self.value = value
...
...     def __eq__(self, other):
...         return self.value == other.value
...
>>> queue.put(A(1))
>>> queue.put(None)
>>>
>>> # And then this happens inside your 'generic' code (which probably even passed your unit tests).
...
>>> list(iter(queue.get, None))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in __eq__
AttributeError: 'NoneType' object has no attribute 'value'
>>>
>>> # Oh... yeah. I really *did* want 'is None' and not '== None' which iter() will do. Sorry guys!

Please don't let this happen to you too ;)



More information about the Python-list mailing list