2013-11-14 17 views
6

Mã này bên dưới các công trình đúng:hiểu lầm năng suất python

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 

Nhưng chức năng này làm tăng StopIteration. Tôi không hiểu tại sao?

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 
+5

Bạn mong đợi điều gì sẽ xảy ra? – delnan

+3

Lỗi thứ hai thực sự là lỗi cú pháp trong Python (bạn không thể thụt lề dòng 'yield') – 6502

+0

@ 6502 xin lỗi, tôi đã chỉnh sửa –

Trả lời

4

Bạn có:

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

Thông báo line = f.readline() này chỉ đọc 1 dòng từ tập tin.

Hãy so sánh:

def g(x): 
    li=range(x) 
    yield li.pop() 

print list(g(10)) 
# [9] 

với điều này:

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 chỉ có thể được gọi là một lần với một đối tượng hoặc biểu hiện cụ thể. Một khi nó được sử dụng bởi người nhận nó phải được tái sinh. Vì vậy, bạn cần một vòng lặp xung quanh đọc từng dòng của tập tin.

Bạn có thể sử dụng thứ hai (ít có thể đọc được) hình thành theo cách này của bạn:

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

Bạn cần một vòng lặp để tạo ra các mục để mang lại. Trong trường hợp đầu tiên của bạn, for line in f: yield line là một vòng lặp.

tôi sẽ viết lại chức năng của bạn theo cách này:

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

thx, nhưng tôi không hiểu những gì sai trong mẫu của tôi? –

+1

@ A.M.Sultanov: Vì 'line = f.readline()' chỉ đọc 1 dòng. Bạn cần bọc nó trong một dạng vòng lặp nào đó - vòng lặp 'while' của vòng lặp' for' dễ đọc hơn – dawg

+0

@darwig thx, tôi nhận ra) –

1

không

line = f.readline() 

chỉ cung cấp cho bạn một dòng để mang lại? do đó lặp dừng lại sau đó ...

+0

nhưng nếu sử dụng biểu mẫu này: file = open ('foo.html') file.readline() file.readline() ... nó không dừng lại trên dòng thứ hai –

+0

Khi tôi thử nó chỉ cho tôi dòng thứ hai thay vì dòng thứ nhất, sau đó dừng lặp lại các cuộc gọi tiếp theo() tiếp theo, như tôi mong đợi. Nhưng dù sao đi nữa, có vẻ như bạn đã đến đáy vấn đề của mình ... – gonkan

2

Bạn nhận được StopIteration trên cạnh thứ hai() bởi vì bạn đã chỉ mang lại một kết quả. Bạn có ý định làm điều này thay thế không?

def file_gen(f_name): 
    f = open(f_name) 
    lines = f.readlines() 
    for line in lines: 
     yield line 
Các vấn đề liên quan