This code below works correct :
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 function raises StopIteration. I don't 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
                You have:
def file_gen(f_name):
    f = open(f_name)
    line = f.readline()
    yield line
Notice line = f.readline() This only reads 1 line from the file.
Compare:
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 particular object or expression. Once it is 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 this way:
def file_gen(f_name):
    f = open(f_name)
    while True:
        line = f.readline()
        if not line:
            break
        yield line
You need a loop to create the the items to yield. In your first case, for line in f: yield line is a loop. 
I would rewrite your function this way:
def file_gen(f_name):
    with open(f_name) as f:
        for line in f:
            yield line
                        You get StopIteration on the second next() because you've only yielded one result. Did you mean to do this instead?
def file_gen(f_name):
    f = open(f_name)
    lines = f.readlines()
    for line in lines:
        yield line
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With