fileinput --- پیمایش سطرها از چندین جریان ورودی

کد منبع: Lib/fileinput.py


این ماژول یک کلاس کمکی و توابعی را پیاده‌سازی می‌کند تا به‌سرعت حلقه‌ای روی ورودی استاندارد یا فهرستی از پرونده‌ها بنویسید. اگر فقط می‌خواهید یک پرونده را بخوانید یا بنویسید، open() را ببینید.

استفاده معمول به این صورت است:

import fileinput
for line in fileinput.input(encoding="utf-8"):
    process(line)

این تابع بر سطرهای تمام پرونده‌های فهرست‌شده در sys.argv[1:] پیمایش می‌کند و اگر فهرست خالی باشد، به‌طور پیش‌فرض از sys.stdin استفاده می‌کند. اگر نام پرونده '-' باشد، آن نیز با sys.stdin جایگزین می‌شود و آرگومان‌های اختیاری mode و openhook نادیده گرفته می‌شوند. برای مشخص کردن فهرستی جایگزین از نام پرونده‌ها، آن را به‌عنوان اولین آرگومان به input() ارسال کنید. یک نام پرونده تکی نیز مجاز است.

همه‌ی پرونده‌ها به‌طور پیش‌فرض در حالت متنی باز می‌شوند، اما شما می‌توانید با تعیین پارامتر mode در فراخوانی input() یا FileInput این پیش‌فرض را تغییر دهید. اگر هنگام باز کردن یا خواندن یک پرونده، خطای I/O رخ دهد، OSError پرتاب می‌شود.

تغییر یافته در نسخه‌ی 3.3: IOError پیش‌تر پرتاب می‌شد؛ اکنون نام مستعاری از OSError است.

اگر از sys.stdin بیش از یک بار استفاده شود، استفاده‌ی دوم و استفاده‌های بعدی هیچ سطری را برنمی‌گردانند، مگر شاید در استفاده‌ی تعاملی، یا اگر به‌صراحت بازنشانی شده باشد (مثلاً با استفاده از sys.stdin.seek(0)).

پرونده‌های خالی باز می‌شوند و بلافاصله بسته می‌شوند؛ تنها زمانی وجود آن‌ها در فهرست نام پرونده‌ها اصلاً محسوس است که آخرین پرونده بازشده خالی باشد.

سطرها به‌همراه نویسه‌های خط جدید دست‌نخورده بازگردانده می‌شوند؛ این بدان معناست که ممکن است آخرین خط یک پرونده فاقد آن باشد.

شما می‌توانید با فراهم کردن یک قلاب باز کردن (opening hook) از طریق پارامتر openhook به fileinput.input() یا FileInput()، چگونگی باز شدن پرونده‌ها را کنترل کنید. قلاب باید تابعی باشد که دو آرگومان، filename و mode، را دریافت می‌کند و شیء شبه‌پرونده‌ای را که به‌صورت متناسب باز شده است برمی‌گرداند. اگر encoding و/یا errors تعیین شده باشند، آن‌ها به‌عنوان آرگومان‌های کلیدواژه‌ای اضافی به قلاب ارسال می‌شوند. این ماژول hook_compressed() را برای پشتیبانی از پرونده‌های فشرده فراهم می‌کند.

تابع زیر رابط اصلی این ماژول است:

fileinput.input(files=None, inplace=False, backup='', *, mode='r', openhook=None, encoding=None, errors=None)

یک نمونه از کلاس FileInput ایجاد می‌کند. این نمونه به‌عنوان وضعیت سراسری برای توابع این ماژول استفاده می‌شود و همچنین برای استفاده در حین تکرار بازگردانده می‌شود. پارامترهای این تابع به سازنده‌ی کلاس FileInput منتقل می‌شوند.

می‌توان از نمونه‌ی FileInput به‌عنوان مدیر زمینه در دستور with استفاده کرد. در این مثال، input پس از خروج از دستور with بسته می‌شود، حتی اگر استثنایی رخ دهد:

with fileinput.input(files=('spam.txt', 'eggs.txt'), encoding="utf-8") as f:
    for line in f:
        process(line)

تغییر یافته در نسخه‌ی 3.2: می‌تواند به‌عنوان یک مدیر زمینه استفاده شود.

تغییر یافته در نسخه‌ی 3.8: پارامترهای کلیدواژه‌ای mode و openhook اکنون فقط کلیدواژه‌ای هستند.

تغییر یافته در نسخه‌ی 3.10: پارامترهای فقط کلیدواژه‌ای encoding و errors افزوده شدند.

توابع زیر از وضعیت سراسری ایجادشده توسط fileinput.input() استفاده می‌کنند؛ اگر وضعیت فعالی وجود نداشته باشد، RuntimeError پرتاب می‌شود.

fileinput.filename()

نام پرونده‌ای را که در حال حاضر خوانده می‌شود برمی‌گرداند. پیش از خوانده شدن خط اول، None را برمی‌گرداند.

fileinput.fileno()

عدد صحیح «توصیف‌گر پرونده» برای پرونده جاری را برمی‌گرداند. هنگامی که هیچ پرونده‌ای باز نیست (پیش از نخستین خط و میان پرونده‌ها)، -1 را برمی‌گرداند.

fileinput.lineno()

شماره‌ی خط تجمعیِ سطری را که به‌تازگی خوانده شده است برمی‌گرداند. پیش از خوانده شدن نخستین خط، 0 را برمی‌گرداند. پس از خوانده شدن آخرین خط از آخرین پرونده، شماره آن خط را برمی‌گرداند.

fileinput.filelineno()

شماره‌ی خط در پرونده جاری را برمی‌گرداند. پیش از خوانده شدن اولین خط، 0 را برمی‌گرداند. پس از خوانده شدن آخرین خط از آخرین پرونده، شماره‌ی آن خط در آن پرونده را برمی‌گرداند.

fileinput.isfirstline()

اگر سطری که به‌تازگی خوانده شده است اولین خط پرونده خود باشد، True برمی‌گرداند، در غیر این صورت False برمی‌گرداند.

fileinput.isstdin()

اگر آخرین خط از sys.stdin خوانده شده باشد، True را برمی‌گرداند، در غیر این صورت False را برمی‌گرداند.

fileinput.nextfile()

پرونده جاری را می‌بندد تا در تکرار بعدی، اولین خط از پرونده بعدی (در صورت وجود) خوانده شود؛ سطرهایی که از پرونده خوانده نشده‌اند، در شمارش تجمعی سطرها به حساب نمی‌آیند. نام پرونده تا پس از خوانده شدن اولین خط از پرونده بعدی تغییر نمی‌کند. پیش از خوانده شدن اولین خط، این تابع هیچ اثری ندارد؛ نمی‌توان از آن برای پرش از اولین پرونده استفاده کرد. پس از خوانده شدن آخرین خط از آخرین پرونده، این تابع هیچ اثری ندارد.

fileinput.close()

دنباله را ببندید.

کلاسی که رفتار دنباله‌ای ارائه‌شده توسط ماژول را پیاده‌سازی می‌کند، برای زیرکلاس‌سازی نیز در دسترس است:

class fileinput.FileInput(files=None, inplace=False, backup='', *, mode='r', openhook=None, encoding=None, errors=None)

کلاس FileInput پیاده‌سازی است؛ متدهای آن filename()، fileno()، lineno()، filelineno()، isfirstline()، isstdin()، nextfile() و close() با توابع هم‌نام در ماژول مطابقت دارند. علاوه بر این، این کلاس پیمایش‌پذیر است و یک متد readline() دارد که خط ورودی بعدی را برمی‌گرداند. این دنباله باید اکیداً به ترتیب پیاپی دسترسی یابد؛ دسترسی تصادفی و readline() نمی‌توانند با هم ترکیب شوند.

با mode می‌توانید مشخص کنید که کدام حالت پرونده به open() ارسال می‌شود. این مقدار باید یکی از 'r' و 'rb' باشد.

openhook، در صورت ارائه، باید تابعی باشد که دو آرگومان filename و mode را می‌گیرد و یک شیء شبه‌پرونده را که به‌طور متناسب بازشده است برمی‌گرداند. شما نمی‌توانید inplace و openhook را با هم استفاده کنید.

می‌توانید encoding و errors را که به open() یا openhook فرستاده می‌شوند، مشخص کنید.

یک نمونه از FileInput می‌تواند به‌عنوان مدیر زمینه در دستور with استفاده شود. در این مثال، input پس از خروج از دستور with بسته می‌شود، حتی اگر یک استثنا رخ دهد:

with FileInput(files=('spam.txt', 'eggs.txt')) as input:
    process(input)

تغییر یافته در نسخه‌ی 3.2: می‌تواند به‌عنوان یک مدیر زمینه استفاده شود.

تغییر یافته در نسخه‌ی 3.8: پارامترهای mode و openhook اکنون فقط کلیدواژه‌ای هستند.

تغییر یافته در نسخه‌ی 3.10: پارامترهای فقط کلیدواژه‌ای encoding و errors افزوده شدند.

تغییر یافته در نسخه‌ی 3.11: حالت‌های 'rU' و 'U' و متد __getitem__() حذف شده‌اند.

فیلتر کردن اختیاری درجا: اگر آرگومان کلیدواژه‌ای inplace=True به fileinput.input() یا به سازنده‌ی FileInput داده شود، پرونده به یک پرونده پشتیبان منتقل می‌شود و خروجی استاندارد به پرونده ورودی هدایت می‌شود (اگر پرونده‌ای با همان نام پرونده پشتیبان از قبل وجود داشته باشد، به‌صورت بی‌صدا جایگزین می‌شود). این کار نوشتن فیلتری را ممکن می‌سازد که پرونده ورودی خود را درجا بازنویسی کند. اگر پارامتر backup داده شود (معمولاً به‌صورت backup='.<some extension>')، پسوند پرونده پشتیبان را مشخص می‌کند و پرونده پشتیبان باقی می‌ماند؛ به‌طور پیش‌فرض، پسوند '.bak' است و پرونده پشتیبان وقتی پرونده خروجی بسته می‌شود، حذف می‌شود. فیلتر کردن درجا هنگامی که ورودی استاندارد خوانده می‌شود، غیرفعال است.

این ماژول دو قلاببازکننده‌ی زیر را فراهم می‌کند:

fileinput.hook_compressed(filename, mode, *, encoding=None, errors=None)

به‌صورت شفاف پرونده‌های فشرده‌شده با gzip و bzip2 را (که با پسوندهای '.gz' و '.bz2' شناخته می‌شوند) با استفاده از ماژول‌های gzip و bz2 باز می‌کند. اگر پسوند نام پرونده '.gz' یا '.bz2' نباشد، پرونده به‌صورت عادی باز می‌شود (یعنی با استفاده از open() بدون هیچ‌گونه واگشایی).

مقادیر encoding و errors برای پرونده‌های فشرده به io.TextIOWrapper و برای پرونده‌های عادی به open ارسال می‌شوند.

مثال استفاده: fi = fileinput.FileInput(openhook=fileinput.hook_compressed, encoding="utf-8")

تغییر یافته در نسخه‌ی 3.10: پارامترهای فقط کلیدواژه‌ای encoding و errors افزوده شدند.

fileinput.hook_encoded(encoding, errors=None)

قلابی را برمی‌گرداند که هر پرونده را با open() باز می‌کند و برای خواندن پرونده، از encoding و errors داده‌شده استفاده می‌کند.

مثال استفاده: fi = fileinput.FileInput(openhook=fileinput.hook_encoded("utf-8", "surrogateescape"))

تغییر یافته در نسخه‌ی 3.6: پارامتر اختیاری errors افزوده شد.

منسوخ شده از نسخه‌ی 3.10: این تابع منسوخ شده است، زیرا fileinput.input() و FileInput اکنون پارامترهای encoding و errors دارند.