مقدمه

هر زمان که در حین اجرای یک برنامه پایتون خطایی رخ دهد، پایتون یک «استثنا» (exception) ایجاد می‌کند. اگر برنامه شما این استثنا را مدیریت نکند، اجرا متوقف شده و یک traceback نمایش داده می‌شود. مدیریت استثناها به شما اجازه می‌دهد تا به صورت کنترل‌شده به خطاهای زمان اجرا واکنش نشان دهید و از کرش کردن برنامه جلوگیری کنید. این کار به خصوص زمانی که با ورودی‌های غیرقابل پیش‌بینی از کاربر یا منابع خارجی (مانند فایل‌ها و شبکه‌ها) سروکار داریم، حیاتی است.

بلاک try-except

برای مدیریت استثناها از بلاک try-except استفاده می‌کنیم. کدی که ممکن است باعث بروز خطا شود را در بلاک try قرار می‌دهیم. اگر در این بلوک خطایی رخ دهد، پایتون به دنبال یک بلوک except می‌گردد که با آن خطا مطابقت داشته باشد و کد داخل آن را اجرا می‌کند.

مدیریت خطای ZeroDivisionError

یکی از خطاهای رایج، تلاش برای تقسیم یک عدد بر صفر است که منجر به استثنای ZeroDivisionError می‌شود.

Copy Icon PYTHON
try:
    print(5 / 0)
except ZeroDivisionError:
    print("You can't divide by zero!")

در این کد، اگر 5 / 0 را مستقیماً اجرا می‌کردیم، برنامه با یک traceback متوقف می‌شد. اما با قرار دادن آن در بلاک try، پایتون استثنا را گرفته و به جای کرش کردن، کد داخل بلاک except را اجرا می‌کند و یک پیام کاربرپسند نمایش می‌دهد.

بلوک else

شما می‌توانید یک بلوک else نیز به این ساختار اضافه کنید. کد داخل بلوک else تنها زمانی اجرا می‌شود که هیچ خطایی در بلاک try رخ ندهد. این به شما اجازه می‌دهد تا کدی را که به موفقیت‌آمیز بودن عملیات در بلوک try وابسته است، از خود آن بلوک جدا کنید.

Copy Icon PYTHON
... # Code to get first_number and second_number from user

try:
    answer = int(first_number) / int(second_number)
except ZeroDivisionError:
    print("You can't divide by zero!")
else:
    print(answer)

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

مدیریت استثنای FileNotFoundError

یکی از رایج‌ترین استثناها هنگام کار با فایل‌ها، FileNotFoundError است که زمانی رخ می‌دهد که تلاش می‌کنیم فایلی را بخوانیم که وجود ندارد.

Copy Icon PYTHON
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.")

این الگو به ما اجازه می‌دهد تا به جای متوقف کردن کل برنامه، به صورت کنترل‌شده به کاربر اطلاع دهیم که فایل مورد نظر پیدا نشده است.

تحلیل متن

حالا بیایید این الگو را گسترش دهیم و تابعی بنویسیم که تعداد کلمات یک فایل را بشمارد و خطاهای احتمالی را مدیریت کند.

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

filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt']
for filename in filenames:
    count_words(filename)

این تابع تلاش می‌کند تا هر فایل را باز کند. اگر فایل وجود نداشته باشد، یک پیام خطا چاپ می‌کند. اگر وجود داشته باشد، تعداد کلمات آن را شمرده و نمایش می‌دهد.

نادیده گرفتن خطاها به صورت بی‌صدا

گاهی اوقات، ما نمی‌خواهیم در صورت بروز خطا هیچ پیامی به کاربر نمایش دهیم و فقط می‌خواهیم برنامه به کار خود ادامه دهد. برای این کار، می‌توانیم از دستور pass در داخل بلوک except استفاده کنیم.

Copy Icon PYTHON
def count_words_silently(filename):
    """Count the approximate number of words in a file, silently ignoring errors."""
    try:
        # ... (same as before) ...
    except FileNotFoundError:
        pass # Do nothing if the file doesn't exist.
    else:
        # ... (same as before) ...

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

در این درس با مکانیزم مدیریت استثناها در پایتون با استفاده از بلاک try-except-else آشنا شدیم. دیدیم که چگونه می‌توان با این ساختار، خطاهای زمان اجرا را به صورت کنترل‌شده مدیریت کرد و از کرش کردن برنامه جلوگیری نمود. در درس بعدی، به «ذخیره‌سازی داده‌ها» با استفاده از ماژول json خواهیم پرداخت تا بتوانیم ساختارهای داده پیچیده پایتون را در فایل‌ها ذخیره و بازیابی کنیم.