قراءة نفس الملف عدة مرات في بيثون
سؤال
أحتاج إلى تنزيل أرشيف مضغوط للملفات النصية ، وإرسال كل ملف نصي في الأرشيف إلى معالجات آخرين للمعالجة ، وأخيراً اكتب الملف النصي غير المدمج إلى القرص.
لدي الرمز التالي. يستخدم متعددة مفتوحة/إغلاق على نفس الملف ، والذي لا يبدو أنيقًا. كيف أجعلها أكثر أناقة وفعالية؟
zipped = urllib.urlopen('www.abc.com/xyz.zip')
buf = cStringIO.StringIO(zipped.read())
zipped.close()
unzipped = zipfile.ZipFile(buf, 'r')
for f_info in unzipped.infolist():
logfile = unzipped.open(f_info)
handler1(logfile)
logfile.close() ## Cannot seek(0). The file like obj does not support seek()
logfile = unzipped.open(f_info)
handler2(logfile)
logfile.close()
unzipped.extract(f_info)
المحلول
إجابتك في رمز المثال الخاص بك. ما عليك سوى استخدام Stringio للتخزين المؤقت لعملية تسجيل الدخول:
zipped = urllib.urlopen('www.abc.com/xyz.zip')
buf = cStringIO.StringIO(zipped.read())
zipped.close()
unzipped = zipfile.ZipFile(buf, 'r')
for f_info in unzipped.infolist():
logfile = unzipped.open(f_info)
# Here's where we buffer:
logbuffer = cStringIO.StringIO(logfile.read())
logfile.close()
for handler in [handler1, handler2]:
handler(logbuffer)
# StringIO objects support seek():
logbuffer.seek(0)
unzipped.extract(f_info)
نصائح أخرى
يمكنك أن تقول شيئًا مثل:
handler_dispatch(logfile)
و
def handler_dispatch(file):
for line in file:
handler1(line)
handler2(line)
أو حتى اجعلها أكثر ديناميكية من خلال بناء فئة معالج ذات وظائف متعددة معالجة ، وتطبيق كل منها في الداخل handler_dispatch
. يحب
class Handler:
def __init__(self:)
self.handlers = []
def add_handler(handler):
self.handlers.append(handler)
def handler_dispatch(self, file):
for line in file:
for handler in self.handlers:
handler.handle(line)
افتح ملف zip مرة واحدة ، وقم بحلق من خلال جميع الأسماء ، واستخلص الملف لكل اسم ومعالجته ، ثم اكتبه على القرص.
مثل ذلك:
for f_info in unzipped.info_list():
file = unzipped.open(f_info)
data = file.read()
# If you need a file like object, wrap it in a cStringIO
fobj = cStringIO.StringIO(data)
handler1(fobj)
handler2(fobj)
with open(filename,"w") as fp:
fp.write(data)
انت وجدت الفكرة
لا تنتمي إلى StackOverflow