Reputation: 641
I have the following function:
| def line_reader_iter(file_object):
| while True:
| a_line = file_object.readline()
| if len(a_line)==0: raise StopIteration
| yield a_line[:-1]
and somewhere I say:
| line_reader = lambda: next(line_reader_iter(infile))
Clearly, the lambda only works because there seems to be a difference in compile-time vs. run-time behaviour which is very welcome: the line_reader_iter() puts the reference to the iterator object into the lambda expression instead of the creation of a generator object each time the lambda is evaluated. BUT: is this portable and stable behaviour? I am just a Python novice and I don't know if my code is in a grey area with respect to the Python execution model. Can someone enligthen me?
slarti
Upvotes: 3
Views: 1850
Reputation: 208565
I think you are actually misunderstanding why this works. Each time you call line_reader()
a new line_reader_iter
generator is created. It appears to work because you use the same infile
each time, and each call to readline()
will return the next line of the file.
Consider the following simpler example:
>>> counter = lambda: next(iter(range(10)))
>>> counter()
0
>>> counter() # each time the lambda is called, a new range iter is created
0
You can get the behavior you want by using the following:
line_reader = line_reader_iter(infile).next
Here is how this would work with my range example:
>>> counter = iter(range(10)).next
>>> counter()
0
>>> counter() # yay, we are actually using the same iterator
1
Upvotes: 7