خواندن خط به خط

اغلب هنگامِ خواندنِ یک فایل نیاز دارید هر خطّ آن را بررسی کنید. شاید به دنبال اطّلاعات خاصّی در فایل باشید یا بخواهید متن داخل آن را به شکلی تغییر دهید. برای مثال ممکن است بخواهید فایلی از داده‌های هواشناسی را بخوانید و با خط‌هایی که در توضیح آب و هوای آن روز عبارت sunny (آفتابی) داشته باشد کاری انجام دهید. در گزارش اخبار ممکن است به دنبال خط‌هایی با برچسب <headline> باشید و به آن خط شکل خاصّی بدهید.

برای بررسی خط به خط یک فایل می‌توانید با حلقه‌ی for در شیء فایل حلقه بزنید:

1
2
3
4
5
filename = 'pi_digits.txt'

with open(filename) as file_object:
    for line in file_object:
        print(line)

در ۱ نام فایلی را که در حال خواندن آن هستیم به متغیّر filename نسبت می‌دهیم. این رویّه‌ای مرسوم برای کار کردن با فایل‌هاست. چون متغیّر filename بیانگر یک فایل واقعی نیست—فقط رشته‌ای است که به پایتون جای فایل را نشان می‌دهد—می‌توانید 'pi_digits.txt' را با نام فایل دیگری جابه‌جا کنید که می‌خواهید با آن کار کنید. پس از فراخوانی open() شیءای که بیانگر فایل است و محتویّات آن را به متغیّر file_object نسبت می‌دهیم (۲). دوباره از دستور with استفاده می‌کنیم تا به پایتون اجازه دهیم فایل را به طور مناسب باز و بسته کند. برای بررسی محتویّات فایل، در شیء فایل حلقه می‌زنیم و با هر خطّ فایل کار می‌کنیم (۳).

وقتی هر خط را چاپ می‌کنیم، به فاصله‌های خالی بیشتری بین خط‌ها برمی‌خوریم:

1
2
3
4
5
3.1415926535

  8979323846

  2643383279

این خط‌های خالی به این دلیل پدیدار می‌شوند که در فایل متنی در پایان هر خط یک کاراکتر خطّ جدید پنهان وجود دارد. تابع print هم که پس از هر بار فراخوانی یک خطّ جدید اضافه می‌کند، در نتیجه در پایان هر خط در مجموع به دو خطّ خالی برمی‌خوریم: یکی از فایل و یکی هم به خاطر print(). هنگام فراخوانی print() با به‌کارگیری rstrip() برای هر خط این خط‌های خالی اضافی حذف می‌شوند:

1
2
3
4
5
filename = 'pi_digits.txt'

with open(filename) as file_object:
    for line in file_object:
        print(line.rstrip())

اکنون بار دیگر خروجی مشابه محتویّات فایل می‌شود.

ساختن لیستی از خط‌های یک فایل

زمانی که از with استفاده می‌کنید شیء فایلی که open() برمی‌گرداند تنها داخل همان بخش with() در دسترس است که آن را در برگرفته. اگر بخواهید دسترسی به محتویّات فایل را پس از قسمت with هم حفظ کنید، می‌توانید در داخل بخش with خط‌های فایل را در لیستی ذخیره کنید و بعداً با آن لیست کار کنید. می‌توانید بخش‌هایی از فایل را بلافاصله پس از خواندن پردازش کنید و بخشی دیگر از پردازش را به زمان دیگری موکول کنید.

مثال زیر خط‌های pi_digits.txt را در داخل بخش with در یک لیست ذخیره می‌کند و سپس خارج از آن، خط‌ها را چاپ می‌کند:

1
2
3
4
5
6
7
filename = 'pi_digits.txt'

with open(filename) as file_object:
    lines = file_object.readlines()

for line in lines:
    print(line.rstrip())

در ۱ متد readlines() هر خطّ فایل را در یک لیست ذخیره می‌کند. سپس این لیست به lines نسبت داده می‌شود که می‌توانیم پس از پایان بخش with هم با آن کار کنیم. در ۲ از یک حلقه‌ی for ساده برای چاپ کردن هر خط در lines استفاده می‌کنیم. از آن‌جایی‌که هر عضو lines متناظر با یک خطّ فایل است، خروجی عیناً مشابه محتویّات فایل خواهد بود.