Facundo Batista wrote:
2008/7/3 George Sakkis
: There is already an idiom for this, although admittedly not obvious or well-known:
for data in iter(lambda: my_file.read(1024), ''): do_something(data)
or in 2.5+:
from functools import partial for data in iter(partial(my_file.read,1024), ''): do_something(data)
Yes, but note that these feels like workarounds.
I disagree, and will explain. To me, iterators are one of the great unifying concept of Python, and for statements are the canonical way to iterate. The end of a sequence, if there is one, can be signaled by any sentinel object or exception. The iterator protocol abstracts away the different possible signals and replaces them all with one exception used just for this purpose and which therefore cannot conflict with any object in the sequence nor be confused with any unexpected exception raised by their production. When used in a for statement, it separates the concern of detecting the end of the sequence from the concern of processing the items of the sequence. So, in this view, making a block-reading-and-yielding iterator, if one does not exist out of the box, is the proper thing to do for processing blocks. While statements are for all other loops for which for statements do not work (including, sometimes, the code buried within a generator function). The suggestion of 'while <expression> as <name>' proposes a new 'expression-iterator' protocol for expression-produced sequences of non-null objects terminated by *any* null object. -1 from me, because a) It unnecessarily duplicates one of Python's gems. b) The use of *all* null objects as sentinels is almost never what one wants in any particular situation. If it is, it is easy enough to write def non_nulls(f): while True: o = f() if o: yield o else: raise StopIteraton # or just break c) Using all nulls as sentinels restricts the sequence more than using just one. It is also bug bait. Suppose f returns next_number or None. A slightly naive or careless programmer writes 'while f as x: ...'. At some point, f returns 0. Whoops. It is better to be specific and only terminate on the intended terminator. For this example, iter(f,None), or iter(f,'' as George suggested for the OP's use case. Careful programming is *not* a workaround. Terry Jan Reedy