2009-05-05 33 views
21

Tôi đang viết một tập lệnh ghi nhật ký lỗi từ một chương trình khác và khởi động lại chương trình mà nó đã dừng lại khi gặp lỗi. Vì lý do nào đó, các nhà phát triển của chương trình này không cảm thấy cần thiết để đưa chức năng này vào chương trình của họ theo mặc định.Trộn các tệp và vòng

Dù sao, chương trình sẽ lấy tệp đầu vào, phân tích cú pháp và tạo tệp đầu ra. Các tập tin đầu vào là trong một định dạng cụ thể:

UI - 26474845 
TI - the title (can be any number of lines) 
AB - the abstract (can also be any number of lines) 

Khi chương trình ném một lỗi, nó mang lại cho bạn những thông tin tham khảo bạn cần phải theo dõi các lỗi - cụ thể là, giao diện người dùng, trong đó phần (tiêu đề hoặc trừu tượng), và số dòng tương ứng với phần đầu của tiêu đề hoặc tóm tắt. Tôi muốn đăng nhập các câu vi phạm từ tệp đầu vào bằng hàm có số tham chiếu và tệp, tìm câu và ghi lại. Cách tốt nhất tôi có thể nghĩ đến việc thực hiện nó liên quan đến việc di chuyển về phía trước thông qua tập tin một số lần cụ thể (cụ thể là, n lần, trong đó n là số dòng tương ứng với đầu của seciton). Cách mà dường như làm cho tinh thần để làm điều này là:

i = 1 
while i <= lineNumber: 
    print original.readline() 
    i += 1 

Tôi không thấy như thế nào điều này sẽ làm cho tôi mất dữ liệu, nhưng Python nghĩ rằng nó sẽ, và nói ValueError: Mixing iteration and read methods would lose data. Có ai biết làm thế nào để làm điều này đúng không?

+1

-1: Mã mất tích từ đoạn. Có thể có chữ "for something in original:" bị thiếu trong đoạn mã được hiển thị. –

Trả lời

44

Bạn nhận được ValueError vì mã của bạn có thể có for line in original: ngoài original.readline(). Một giải pháp đơn giản mà sửa chữa vấn đề mà không làm chương trình của bạn chậm hoặc tiêu thụ bộ nhớ hơn là thay đổi

for line in original: 
    ... 

để

while True: 
    line = original.readline() 
    if not line: break 
    ... 
+1

Bạn chạm vào móng trên đầu - I * đã được * sử dụng cho, cũng như trong khi. Đây là bản sửa lỗi nhanh nhất. Cảm ơn, và cảm ơn cho phản ứng của mọi người là tốt. –

+0

cũng giúp tôi. cảm ơn bạn. – nish

+0

Điều này dường như không hoạt động. Nó đi vào một vòng lặp vô hạn. Tôi tin rằng eof không trả về giá trị None. – lionel319

10

Sử dụng forenumerate.

Ví dụ:

for line_num, line in enumerate(file): 
    if line_num < cut_off: 
     print line 

LƯU Ý: Điều này giả định bạn đã dọn dẹp xử lý tập tin của bạn, vv

Ngoài ra, các takewhile chức năng có thể hữu ích nếu bạn muốn có một hương vị chức năng hơn.

0

Giả sử bạn chỉ cần một dòng, điều này có thể giúp đỡ

import itertools 

def getline(fobj, line_no): 
    "Return a (1-based) line from a file object" 
    return itertools.islice(fobj, line_no-1, line_no).next() # 1-based! 

>>> print getline(open("/etc/passwd", "r"), 4) 
'adm:x:3:4:adm:/var/adm:/bin/false\n' 

Bạn có thể muốn bắt lỗi StopIteration (nếu tệp có ít dòng hơn).

0

Dưới đây là một phiên bản mà không có sự while True mẫu xấu xí và không có các module khác:

for line in iter(original.readline, ''): 
    if …: # to the beginning of the title or abstract 
     for i in range(lineNumber): 
      print original.readline(), 
     break 
Các vấn đề liên quan