2009-11-27 38 views
7

Giả sử bạn mở một tệp và tìm kiếm() ở đâu đó trong tệp, làm cách nào để bạn biết dòng tệp hiện tại?Cách lấy dòng tệp đang mở trong python?

(Cá nhân tôi đã giải quyết bằng lớp tệp đặc biệt để ánh xạ vị trí tìm kiếm vào dòng sau khi quét tệp, nhưng tôi muốn xem các gợi ý khác và thêm câu hỏi này vào stackoverflow, vì tôi không thể tìm thấy vấn đề ở bất cứ đâu trên google)

+0

Tôi thực sự đăng lớp học ở đâu đó ở đây trên SO ... không biết ở đâu. –

+1

Nếu bạn đang tìm cách bù đắp byte, không có cách nào để biết dòng # mà không đếm số lượng \ n ký tự gặp phải trước vị trí đó. Như những gì cách hiệu quả nhất là với một tập tin, tôi không chắc chắn .... Chúc may mắn! – gahooa

+0

yep. có thể có một số thư viện thực hiện dịch vụ này. Tôi đã tự mình thực hiện nó như tôi đã nói, nhưng tôi muốn ủy quyền tác vụ này cho một thư viện bên ngoài nếu có thể. –

Trả lời

4

đây là cách tôi sẽ tiếp cận vấn đề, sử dụng càng nhiều sự lười biếng càng tốt:

from random import randint 
from itertools import takewhile, islice 

file = "/etc/passwd" 
f = open(file, "r") 

f.seek(randint(10,250)) 
pos = f.tell() 

print "pos=%d" % pos 

def countbytes(iterable): 
    bytes = 0 
    for item in iterable: 
     bytes += len(item) 
     yield bytes 

print 1+len(list(takewhile(lambda x: x <= pos, countbytes(open(file, "r"))))) 

Đối với một cách tiếp cận hơi ít có thể đọc nhưng nhiều hơn nữa lười biếng, sử dụng enumeratedropwhile:

from random import randint 
from itertools import islice, dropwhile 

file = "/etc/passwd" 
f = open(file, "r") 

f.seek(randint(10,250)) 
pos = f.tell() 

print "pos=%d" % pos 

def countbytes(iterable): 
    bytes = 0 
    for item in iterable: 
     bytes += len(item) 
     yield bytes 

print list(
     islice(
      dropwhile(lambda x: x[1] <= pos, enumerate(countbytes(open(file, "r")))) 
      , 1))[0][0]+1 
+0

sử dụng mát mẻ các công cụ lặp lại ... :) –

6

Khi bạn sử dụng hàm tìm kiếm(), python sẽ sử dụng bù trừ con trỏ để chuyển đến vị trí mong muốn trong tệp. Nhưng để biết số dòng hiện tại, bạn phải kiểm tra từng nhân vật đến vị trí đó. Vì vậy, bạn cũng có thể từ bỏ tìm kiếm() ủng hộ read():

Thay

f = open(filename, "r") 
f.seek(55) 

với

f = open(filename, "r") 
line=f.read(55).count('\n')+1 
print(line) 

Có lẽ bạn không muốn sử dụng f.read (num) kể từ điều này có thể yêu cầu rất nhiều bộ nhớ nếu num là rất lớn. Trong trường hợp đó, bạn có thể sử dụng một máy phát điện như thế này:

import itertools 
import operator 
line_number=reduce(operator.add,(f.read(1)=='\n' for _ in itertools.repeat(None,num))) 
pos=f.tell() 

này tương đương với f.seek(num) với lợi ích bổ sung cho bạn line_number.

Các vấn đề liên quan