Incomprehensible income from python

This code below works correctly:

def file_gen(f_name): f = open(f_name) for line in f: yield line gen_line = file_gen("foo.html") gen_line.next() # '<!DOCTYPE>\n' gen_line.next() # '<html> \n' gen_line.next() # ... next line in file 

But this feature rises StopIteration . I do not understand why?

 def file_gen(f_name): f = open(f_name) line = f.readline() yield line gen_line = file_gen('foo.html') gen_line.next() # '<!DOCTYPE>\n' gen_line.next() # StopIteration 
+6
source share
3 answers

You have:

 def file_gen(f_name): f = open(f_name) line = f.readline() yield line 

Note line = f.readline() This is only 1 line from the file.

For comparison:

 def g(x): li=range(x) yield li.pop() print list(g(10)) # [9] 

with this:

 def g(x): li=range(x) while li: yield li.pop() print list(g(10)) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 

yield can only be called once with a specific object or expression. When used by the receiver, it must be regenerated. So you need a loop around reading each line of the file.

You can use your second (less readable) form as follows:

 def file_gen(f_name): f = open(f_name) while True: line = f.readline() if not line: break yield line 

To create return items you need a loop. In your first case, for line in f: yield line is a loop.

I would rewrite your function as follows:

 def file_gen(f_name): with open(f_name) as f: for line in f: yield line 
+4
source

You get StopIteration on the second next () because you got only one result. Did you want to do this instead?

 def file_gen(f_name): f = open(f_name) lines = f.readlines() for line in lines: yield line 
+2
source

not

 line = f.readline() 

gives you only one line? so after that the iteration stops ...

+1
source

Source: https://habr.com/ru/post/958082/


All Articles