رسیدگی به استثنای FileNotFoundError

یکی از مشکلات شایع هنگام کار کردن با فایل‌ها مدیریّت فایل‌های ناموجود است. فایلی که به دنبال آن هستید ممکن است در جای متفاوتی باشد، نام آن ممکن است اشتباه نوشته شده باشد یا چه بسا اصلاً وجود نداشته باشد. شما می‌توانید به کمک یک بلوک try-except و با روشی سرراست به تمام این وضعیّت‌ها رسیدگی کنید.

حال بیایید تلاش کنیم فایلی را که وجود ندارد بخوانیم. برنامه‌ی زیر می‌خواهد محتویّات آلیس در سرزمین عجایب را بخواند امّا من فایل alice.txt را در پوشه‌ی alice.py ذخیره نکرده‌ام:

1
2
3
4
filename = 'alice.txt'

with open(filename, encoding='utf-8') as f:
    contents = f.read()

اینجا دو تغییر وجود دارد. یکی به‌کارگیری متغیّر f برای نمایش شیء فایل است که قراردادی مرسوم است. دیگری استفاده از نشان‌وند encoding است. این نشان‌وند هنگامی مورد نیاز است که کدگذاری پیش‌فرض سیست 97 م شما با کدگذاری فایلی که می‌خواهید بخوانید هم‌خوانی ندارد.

پایتون نمی‌تواند فایلی را که وجود ندارد بخواند پس استثنایی ایجاد می‌کند:

1
2
3
4
Traceback (most recent call last):
  File "alice.py", line 3, in <module>
    with open(filename, encoding='utf-8') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'alice.txt'

آخرین خط traceback خطای FileNotFoundError را گزارش می‌کند: زمانی که پایتون فایلی را که تلاش می‌کند بخواند، پیدا نمی‌کند این استثنا را تولید می‌کند.

در این مثال تابع open() ایجاد خطا می‌کند بنابراین برای رسیدگی به آن، بلوک try از خطّی شروع می‌شود که شامل open() است:

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

try:
    with open(filename, encoding='utf-8') as f:
        contents = f.read()
except FileNotFoundError:
    print(f"Sorry, the file {filename} does not exist.")

در این مثال کد داخل بلوک try ایجاد FileNotFoundError می‌کند پس پایتون به دنبال بلوک except‌ای می‌گردد که به این خطا بخورد. سپس کد داخل آن بلوک را اجرا می‌کند که به جای یک traceback به صدور پیام دوستانه‌ای منجر می‌شود:

1
Sorry, the file alice.txt does not exist.

این برنامه در صورت پیدا نشدن فایل کاری برای انجام دادن ندارد بنابراین رسیدگی به خطا چیز زیادی به آن اضافه نمی‌کند. اجازه دهید این مثال را ادامه دهیم و ببینیم مدیریّت استثناها هنگام کار کردن با بیش از یک فایل چه کمکی می‌توانند بکنند.

تحلیل متن

شما می‌توانید فایل‌های متنی شامل کتاب‌های کامل را98 تحلیل کنید. بخش زیادی از ادبیّات کلاسیک در قالب فایل‌های متنی ساده در دسترس هستند چون در قلمرو عمومی هستند. متن‌های به کار رفته در این بخش از پروژه‌ی گوتنبرگ گرفته شده‌اند (http://gutenberg.org) پروژه‌ی گوتنبرگ مجموعه‌ای از کارهای ادبی را نگه‌داری می‌کند که در قلمرو عمومی در دسترس‌اند و اگر در پروژه‌های برنامه‌نویسی خود به کار با متن‌های ادبی علاقه‌مندید، منبع بسیار خوبی خواهد بود.

اجازه دهید متن آلیس در سرزمین عجایب را بیرون بکشیم تا تعداد کلمات متن آن را بشمریم. از متد رشته‌ای split() استفاده می‌کنیم که می‌تواند رشته را به لیستی از کلمات تبدیل کند. اینجا می‌بینیم که split() با رشته‌ای که شامل عنوان متن یعنی "Alice in Wonderland" است چه می‌کند:

1
2
3
>>> title = "Alice in Wonderland"
>>> title.split()
['Alice', 'in', 'Wonderland']

متد split() هر جا در رشته به فاصله‌ی خالی می‌رسد، آن بخش را جدا کرده و تمام تکّه‌ها را در لیستی ذخیره می‌کند. نتیجه لیستی از کلماتِ رشته است، هرچند ممکن است در برخی از کلمات علائم سجاوندی هم پیدا شود. برای شمارش کلمات آلیس در سرزمین عجایب از split() بر روی کل متن استفاده می‌کنیم. سپس تنها اعضای لیست را می‌شماریم تا به عددی سرانگشتی از تعداد کلمات موجود در متن برسیم:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
filename = 'alice.txt'

try:
    with open(filename, encoding='utf-8') as f:
        contents = f.read()
except FileNotFoundError:
    print(f"Sorry, the file {filename} does not exist.")
else:
    # Count the approximate number of words in the file.
    words = contents.split()
    num_words = len(words)
    print(f"The file {filename} has about {num_words} words.")

فایل alice.txt را به پوشه‌ی درست منتقل کردم بنابراین بلوک try این بار درست کار خواهد کرد. در ۱ رشته‌ی contents را که اکنون کل متن آلیس در سرزمین عجایب را به صورت یک رشته‌ی بلند در بر دارد، می‌گیریم و به کمک متد split() لیستی از تمام کلمات داخل کتاب درست می‌کنیم. زمانی که از len() برای بررسی طول آن استفاده می‌کنیم تقریب خوبی از تعداد کلمات رشته‌ی اصلی به دست می‌آوریم (۲). در ۳ عبارتی چاپ می‌کنیم که تعداد کلمات یافت‌شده در فایل را گزارش می‌کند. این کد داخل بلوک else قرار گرفته زیرا تنها در صورتی کار خواهند کرد که بلوک try با موفقیّت اجرا شود. خروجی به ما می‌گوید که تعداد کلمات موجود در alice.txt چندتاست:

1
The file alice.txt has about 29465 words.

این تعداد کمی از مقدار واقعی بیشتر است زیرا ناشر اطّلاعات بیشتری در فایل متنی به‌کاررفته ارائه کرده است با این حال تقریب خوبی از تعداد کلمات آلیس در سرزمین عجایب است.