سؤال
كيف أتحقق من EOF في بيثون؟ لقد وجدت خطأ في الكود الخاص بي حيث لم يتم إضافة كتلة النص الأخيرة بعد الفاصل إلى قائمة الإرجاع. أو ربما هناك طريقة أفضل للتعبير عن هذه الوظيفة؟
هذا هو الكود الخاص بي:
def get_text_blocks(filename):
text_blocks = []
text_block = StringIO.StringIO()
with open(filename, 'r') as f:
for line in f:
text_block.write(line)
print line
if line.startswith('-- -'):
text_blocks.append(text_block.getvalue())
text_block.close()
text_block = StringIO.StringIO()
return text_blocks
المحلول
قد تجد أنه من الأسهل حل هذا باستخدام itertools.groupby.
def get_text_blocks(filename):
import itertools
with open(filename,'r') as f:
groups = itertools.groupby(f, lambda line:line.startswith('-- -'))
return [''.join(lines) for is_separator, lines in groups if not is_separator]
بديل آخر هو استخدام أ تعبير عادي لمطابقة الفواصل:
def get_text_blocks(filename):
import re
seperator = re.compile('^-- -.*', re.M)
with open(filename,'r') as f:
return re.split(seperator, f.read())
نصائح أخرى
تتمسك حالة نهاية الملف بمجرد for
ينتهي البيان - هذا يبدو أبسط طريقة لإصلاح هذا الرمز بشكل بسيط (يمكنك استخراج text_block.getvalue()
في النهاية إذا كنت تريد التحقق من أنه ليس فارغًا قبل إلحاقه).
هذه هي المشكلة القياسية في مخازن المؤقتة.
أنت لا تكتشف EOF - هذا لا داعي له. تكتب آخر مخزن مؤقت.
def get_text_blocks(filename):
text_blocks = []
text_block = StringIO.StringIO()
with open(filename, 'r') as f:
for line in f:
text_block.write(line)
print line
if line.startswith('-- -'):
text_blocks.append(text_block.getvalue())
text_block.close()
text_block = StringIO.StringIO()
### At this moment, you are at EOF
if len(text_block) > 0:
text_blocks.append( text_block.getvalue() )
### Now your final block (if any) is appended.
return text_blocks
لماذا تحتاج stringio هنا؟
def get_text_blocks(filename):
text_blocks = [""]
with open(filename, 'r') as f:
for line in f:
if line.startswith('-- -'):
text_blocks.append(line)
else: text_blocks[-1] += line
return text_blocks
تحرير: إصلاح الوظيفة ، قد تكون الاقتراحات الأخرى أفضل ، فقط أردت كتابة وظيفة مماثلة للواحدة الأصلية.
تحرير: افتراض أن الملف يبدأ بـ "--" ، عن طريق إضافة سلسلة فارغة إلى القائمة ، يمكنك "إصلاح" IndexerRor أو يمكنك استخدام هذا واحد:
def get_text_blocks(filename):
text_blocks = []
with open(filename, 'r') as f:
for line in f:
if line.startswith('-- -'):
text_blocks.append(line)
else:
if len(text_blocks) != 0:
text_blocks[-1] += line
return text_blocks
لكن كلا الإصدارين تبدو قبيحة بعض الشيء بالنسبة لي ، فإن إصدار Reg-EX أكثر أنظفًا.
هذه طريقة سريعة لمعرفة ما إذا كان لديك ملف فارغ:
if f.read(1) == '':
print "EOF"
f.close()