Python: التراجع عن تشغيل ملف readline () لذا عاد ملف الملف إلى الحالة الأصلية
سؤال
أنا أتصفح مؤشر ملف Python لملف نصي في وضع القراءة فقط باستخدام file.readline () يبحث عن سطر خاص. بمجرد أن أجد هذا السطر ، أريد تمرير مؤشر الملف إلى طريقة تتوقع أن يكون مؤشر الملف في بداية هذا الخط القراءة (ليس بعده مباشرة).
كيف يمكنني التراجع بشكل أساسي عن تشغيل ملف واحد. ReadLine () على مؤشر الملف؟
المحلول
عليك أن تتذكر الموقف عن طريق الاتصال file.tell()
قبل خط القراءة ثم الاتصال file.seek()
لإرجاع. شيء مثل:
fp = open('myfile')
last_pos = fp.tell()
line = fp.readline()
while line != '':
if line == 'SPECIAL':
fp.seek(last_pos)
other_function(fp)
break
last_pos = fp.tell()
line = fp.readline()
لا أستطيع أن أتذكر ما إذا كان من الآمن الاتصال file.seek()
داخل أ for line in file
حلقة لذلك عادة ما أكتب while
عقدة. ربما هناك طريقة أكثر إثارة للقيام بذلك.
نصائح أخرى
تقوم بتسجيل نقطة انطلاق الخط مع thefile.tell()
قبل الاتصال readline
, ، والعودة إلى هذه النقطة ، إذا كنت بحاجة ، مع thefile.seek
.
>>> with open('bah.txt', 'w') as f:
... f.writelines('Hello %s\n' % i for i in range(5))
...
>>> with open('bah.txt') as f:
... f.readline()
... x = f.tell()
... f.readline()
... f.seek(x)
... f.readline()
...
'Hello 0\n'
'Hello 1\n'
'Hello 1\n'
>>>
كما ترى ، فإن Seek/Tell "الزوج" هو "التراجع" ، إذا جاز التعبير ، فإن حركة مؤشر الملفات التي تؤديها readline
. بالطبع ، لا يمكن أن يعمل هذا إلا على ملف فعلي يمكن البحث عنه (أي ، القرص) ، وليس (على سبيل المثال) على الكائنات الشبيهة بالملف المصنفة مع طريقة Makefile للمآخذ ، إلخ ، إلخ.
إذا كانت طريقتك تريد ببساطة التكرار من خلال الملف ، فيمكنك استخدامها itertools.chain
لجعل التكرار المناسب:
import itertools
def process(it):
for line in it:
print line,
with open(filename,'r') as f:
for line in f:
if 'marker' in line:
it=itertools.chain((line,),f)
process(it)
break
fin = open('myfile')
for l in fin:
if l == 'myspecialline':
# Move the pointer back to the beginning of this line
fin.seek(fin.tell() - len(l))
break
# now fin points to the start of your special line
إذا كنت لا تعرف السطر الأخير لأنك لم تزوره ، فيمكنك القراءة للخلف حتى ترى حرفًا جديدًا:
with open(logfile, 'r') as f:
# go to EOF
f.seek(0, os.SEEK_END)
nlines = f.tell()
i=0
while True:
f.seek(nlines-i)
char = f.read(1)
if char=='\n':
break
i+=1