مقدمه
هر زمان که در حین اجرای یک برنامه پایتون خطایی رخ دهد، پایتون یک «استثنا» (exception) ایجاد
میکند. اگر برنامه شما این استثنا را مدیریت نکند، اجرا متوقف شده و یک traceback نمایش داده
میشود. مدیریت استثناها به شما اجازه میدهد تا به صورت کنترلشده به خطاهای زمان اجرا واکنش نشان
دهید و از کرش کردن برنامه جلوگیری کنید. این کار به خصوص زمانی که با ورودیهای غیرقابل پیشبینی
از کاربر یا منابع خارجی (مانند فایلها و شبکهها) سروکار داریم، حیاتی است.
بلاک try-except
برای مدیریت استثناها از بلاک try-except استفاده میکنیم. کدی که ممکن است باعث بروز خطا
شود را در بلاک try قرار میدهیم. اگر در این بلوک خطایی رخ دهد، پایتون به دنبال یک بلوک
except میگردد که با آن خطا مطابقت داشته باشد و کد داخل آن را اجرا میکند.
مدیریت خطای ZeroDivisionError
یکی از خطاهای رایج، تلاش برای تقسیم یک عدد بر صفر است که منجر به استثنای ZeroDivisionError
میشود.
PYTHON
try:
print(5 / 0)
except ZeroDivisionError:
print("You can't divide by zero!")
در این کد، اگر 5 / 0 را مستقیماً اجرا میکردیم، برنامه با یک traceback متوقف میشد. اما با
قرار دادن آن در بلاک try، پایتون استثنا را گرفته و به جای کرش کردن، کد داخل بلاک
except را اجرا میکند و یک پیام کاربرپسند نمایش میدهد.
بلوک else
شما میتوانید یک بلوک else نیز به این ساختار اضافه کنید. کد داخل بلوک else تنها
زمانی اجرا میشود که هیچ خطایی در بلاک try رخ ندهد. این به شما اجازه میدهد تا کدی را که
به موفقیتآمیز بودن عملیات در بلوک try وابسته است، از خود آن بلوک جدا کنید.
PYTHON
...
try:
answer = int(first_number) / int(second_number)
except ZeroDivisionError:
print("You can't divide by zero!")
else:
print(answer)
در این مثال، اگر تقسیم با موفقیت انجام شود، نتیجه آن در بلوک else چاپ میشود. این کار
خوانایی کد را افزایش میدهد، زیرا منطق موفقیت از منطق مدیریت خطا جدا شده است.
مدیریت استثنای FileNotFoundError
یکی از رایجترین استثناها هنگام کار با فایلها، FileNotFoundError است که زمانی رخ میدهد که
تلاش میکنیم فایلی را بخوانیم که وجود ندارد.
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.")
این الگو به ما اجازه میدهد تا به جای متوقف کردن کل برنامه، به صورت کنترلشده به کاربر اطلاع
دهیم که فایل مورد نظر پیدا نشده است.
تحلیل متن
حالا بیایید این الگو را گسترش دهیم و تابعی بنویسیم که تعداد کلمات یک فایل را بشمارد و خطاهای
احتمالی را مدیریت کند.
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
استفاده کنیم.
PYTHON
def count_words_silently(filename):
"""Count the approximate number of words in a file, silently ignoring errors."""
try:
except FileNotFoundError:
pass
else:
استفاده از pass به شما اجازه میدهد تا خطاها را نادیده بگیرید، اما این کار باید با احتیاط
انجام شود، زیرا ممکن است باعث پنهان شدن باگهای واقعی شود.
در این درس با مکانیزم مدیریت استثناها در پایتون با استفاده از بلاک try-except-else آشنا
شدیم. دیدیم که چگونه میتوان با این ساختار، خطاهای زمان اجرا را به صورت کنترلشده مدیریت کرد و
از کرش کردن برنامه جلوگیری نمود. در درس بعدی، به «ذخیرهسازی دادهها» با استفاده از ماژول json
خواهیم پرداخت تا بتوانیم ساختارهای داده پیچیده پایتون را در فایلها ذخیره و بازیابی کنیم.