Table of Contents
درک دقیق try و except در پایتون
در این بخش روی ابزار اصلی مدیریت «خطاهای زمان اجرا» در پایتون تمرکز میکنیم: ساختار try و except. هدف این است که بدانید:
- چه زمانی از
try/exceptاستفاده کنید - شکلهای مختلف نوشتن آن چگونه است
- چطور فقط خطاهای خاص را بگیرید
- چطور هم پیام مناسب به کاربر بدهید و هم برنامه را از توقف ناگهانی نجات دهید
ایدهٔ اصلی try و except
وقتی پایتون به خطایی میرسد که آن را مدیریت نکردهاید، برنامه متوقف میشود و پیام خطا نشان میدهد. با try و except میتوانید به پایتون بگویید:
«این بخش از کد را امتحان کن؛ اگر خطا شد، بهجای کرش کردن، این کار جایگزین را انجام بده.»
ساختار کلی:
try:
# کدی که ممکن است خطا بدهد
...
except:
# کاری که اگر خطا رخ داد باید انجام شود
...مثال ساده:
text = "سلام"
try:
number = int(text) # تلاش برای تبدیل متن به عدد
print("عدد:", number)
except:
print("نمیتوانم این متن را به عدد تبدیل کنم!")
اینجا بدون try/except برنامه با خطای ValueError متوقف میشد، اما حالا پیام خودمان را چاپ میکند و برنامه میتواند ادامه بدهد.
ساختارهای مختلف try و except
۱. try + except ساده
سادهترین حالت:
try:
x = 10 / 0
except:
print("یک خطا رخ داد!")ویژگی این حالت:
- هر نوع خطایی داخل بلاک
tryرخ دهد، توسط اینexceptگرفته میشود. - برای شروع تمرین خوب است، اما در برنامههای واقعی معمولاً توصیه نمیشود، چون:
- نمیدانید دقیقاً چه خطایی رخ داده
- شاید باگ جدی را هم بیصدا ببلعد
۲. گرفتن خطای خاص (توصیهشده)
بهتر است مشخص کنید انتظار «چه نوع» خطایی را دارید. مثال:
user_input = input("یک عدد وارد کنید: ")
try:
number = int(user_input)
print("عدد شما:", number)
except ValueError:
print("لطفاً فقط عدد وارد کنید، نه متن یا حروف.")اینجا:
- تنها اگر تبدیل
int(user_input)خطایValueErrorبدهد، اینexceptفعال میشود. - اگر خطای دیگری مثل
KeyboardInterruptرخ دهد، اینexceptآن را نمیگیرد و برنامه همان خطای اصلی را نشان میدهد.
چرا این کار خوب است؟
چون شما دقیقاً میدانید چه نوع خطایی را مدیریت میکنید و بقیهٔ خطاها همچنان دیده میشوند تا بتوانید آنها را اشکالزدایی کنید.
۳. گرفتن چند نوع خطا با هم
گاهی یک بخش از کد ممکن است چند نوع خطای مرتبط بدهد. میتوانید چند نوع خطا را با هم در یک except بنویسید:
file_name = "data.txt"
try:
f = open(file_name, "r")
content = f.read()
number = int(content)
print("عدد داخل فایل:", number)
except (FileNotFoundError, ValueError):
print("یا فایل پیدا نشد، یا محتوای آن عدد معتبر نیست.")اینجا:
- اگر فایل وجود نداشته باشد →
FileNotFoundError - اگر محتوا قابل تبدیل به عدد نباشد →
ValueError - هر دوی اینها با یک
exceptمدیریت میشوند.
۴. چند except مختلف برای خطاهای متفاوت
اگر بخواهید برای هر نوع خطا رفتار جداگانه داشته باشید، از چند except استفاده میکنید:
file_name = "data.txt"
try:
f = open(file_name, "r")
content = f.read()
number = int(content)
print("عدد داخل فایل:", number)
except FileNotFoundError:
print("فایل پیدا نشد. لطفاً نام فایل را بررسی کنید.")
except ValueError:
print("محتوای فایل عدد معتبر نیست.")قوانین:
- فقط یکی از بلاکهای
exceptاجرا میشود؛ آنکه با اولین خطای رخداده سازگار است. - ترتیب نوشتن
exceptها مهم است؛ پایتون آنها را از بالا به پایین بررسی میکند.
۵. گرفتن خطا و شیء استثنا (as e)
گاهی میخواهید متن دقیق خطا را هم داشته باشید. میتوانید شیء خطا را دریافت کنید:
user_input = input("یک عدد وارد کنید: ")
try:
number = int(user_input)
print("عدد شما:", number)
except ValueError as e:
print("ورودی نامعتبر است.")
print("جزئیات فنی خطا:", e)
اینجا e یک شیء خطاست که معمولاً وقتی آن را چاپ میکنید، توضیح کوتاه انگلیسی خطا را نشان میدهد. این کار برای اشکالزدایی مفید است، حتی اگر به کاربر پیام سادهٔ فارسی بدهید.
استفاده از else با try و except
گاهی میخواهید:
- اگر خطا نشد: یک کار انجام شود
- اگر خطا شد: کار دیگری انجام شود
بهجای اینکه همهٔ کد را در try بگذارید، میتوانید از else استفاده کنید:
user_input = input("یک عدد تقسیمکننده وارد کنید: ")
try:
divider = int(user_input)
except ValueError:
print("لطفاً یک عدد صحیح وارد کنید.")
else:
result = 100 / divider
print("نتیجه تقسیم:", result)اینجا:
- اگر تبدیل به عدد موفق باشد →
elseاجرا میشود. - اگر تبدیل خطا بدهد (
ValueError) →exceptاجرا میشود وelseاجرا نمیشود.
مزیت:
- فقط کدی که «ممکن است خطای تبدیل بدهد» داخل
tryاست. - بقیهٔ منطق برنامه در
elseقرار میگیرد و خوانایی بهتر میشود.
استفاده از finally برای کارهای حتماً لازم
بلاک finally همیشه اجرا میشود؛ چه خطا رخ دهد، چه نه. این برای کارهایی که «حتماً باید انجام شوند» مفید است، مثل بستن فایل یا قطع ارتباط.
ساختار کلی:
try:
# کدی که ممکن است خطا داشته باشد
...
except SomeError:
# واکنش به خطا
...
finally:
# کاری که در هر صورت باید انجام شود
...مثال:
file_name = "data.txt"
try:
f = open(file_name, "r")
content = f.read()
print("محتوای فایل:", content)
except FileNotFoundError:
print("فایل پیدا نشد.")
finally:
print("پایان عملیات خواندن فایل (موفق یا ناموفق).")
اینجا پیام پایان عملیات... در هر حال چاپ میشود.
یک استفادهٔ رایج:
file_name = "data.txt"
f = None
try:
f = open(file_name, "r")
content = f.read()
print("محتوا:", content)
except FileNotFoundError:
print("فایل پیدا نشد.")
finally:
if f is not None:
f.close()
در finally، اگر فایل باز شده باشد، آن را میبندیم؛ چه هنگام خواندن خطا رخ داده باشد، چه نه.
کجا از try/except استفاده کنیم (و کجا نه)؟
موقعیتهای مناسب
- خواندن ورودی از کاربر (
input) و تبدیل آن به عدد (int,float) - باز کردن فایلهایی که ممکن است وجود نداشته باشند
- کار با شبکه و اینترنت (قطع بودن اینترنت، مشکل سرور و …)
- تقسیم عددی که امکان صفر بودن مخرج آن هست
مثال ساده با ترکیب چند ایده:
user_input = input("یک عدد وارد کنید تا 100 را بر آن تقسیم کنم: ")
try:
number = int(user_input)
result = 100 / number
except ValueError:
print("باید یک عدد صحیح وارد کنید.")
except ZeroDivisionError:
print("نمیتوان بر صفر تقسیم کرد!")
else:
print("نتیجه:", result)کارهایی که نباید با try/except بپوشانید
- اشتباهات برنامهنویسی مثل غلطنوشتن اسم متغیر (
NameError) یا اشتباه منطقی در حلقهها. - گذاشتن
try/exceptبزرگ دورِ «کل برنامه» برای مخفی کردن همهٔ خطاها.
این کار باعث میشود:
- باگها پیدا نشوند
- برنامه ظاهراً «بدون خطا» اجرا شود اما خروجی اشتباه بدهد
- اشکالزدایی بسیار سختتر شود
بهتر است:
try/exceptرا دقیقاً دور آن خط یا چند خطی قرار دهید که انتظار خطای مشخص از آن دارید.
الگوهای رایج استفاده از try و except
۱. تکرار تا دریافت ورودی درست
یکی از الگوهای رایج، گرفتن ورودی درست از کاربر است:
while True:
user_input = input("سن خود را وارد کنید: ")
try:
age = int(user_input)
if age < 0:
print("سن نمیتواند منفی باشد.")
else:
break # ورودی معتبر، از حلقه خارج شویم
except ValueError:
print("لطفاً فقط عدد صحیح وارد کنید.")
print("سن شما:", age)اینجا:
- تا زمانی که ورودی نادرست است، پیام مناسب چاپ میشود و دوباره سؤال پرسیده میشود.
breakفقط زمانی اجرا میشود که مقدار معتبر دریافت شده باشد.
۲. تبدیل «احتمال خطا» به مقدار پیشفرض
گاهی اگر خطا شد، میخواهید مقدار پیشفرض بگذارید و ادامه دهید:
user_input = input("یک عدد وارد کنید (خالی بگذارید تا 0 شود): ")
try:
number = int(user_input)
except ValueError:
number = 0 # مقدار پیشفرض
print("عدد نهایی:", number)۳. ثبت پیام خطا برای اشکالزدایی
در برنامههای بزرگتر معمول است هم به کاربر پیام ساده بدهید، هم جزئیات خطا را در جایی (مثلاً لاگ) بنویسید. در حد ساده:
def read_number_from_file(file_name):
try:
with open(file_name, "r") as f:
content = f.read()
return int(content)
except (FileNotFoundError, ValueError) as e:
print("خطا در خواندن عدد از فایل:", file_name)
print("جزئیات فنی:", e)
return None
result = read_number_from_file("data.txt")
print("نتیجه خواندن:", result)چند نکتهٔ عملی دربارهٔ try و except
- تا حد امکان، بلاک
tryرا کوچک نگه دارید.
بهجای:
try:
# کد زیاد
a = int(x)
# کد زیاد
except ValueError:
...بهتر است:
# کد زیاد
try:
a = int(x)
except ValueError:
...
# کد زیاد- در
except، پیامهای مفهوم برای کاربر بنویسید، نه متن انگلیسی و پیچیده. - برای خودِ برنامهنویس، نمایش شیء خطا (
as e) هنگام توسعه مفید است. - از
except:بدون نوع خطا، فقط وقتی استفاده کنید که واقعاً دلیل خوبی دارید؛ و ترجیحاً در مرحلهٔ نهایی برنامه نه، در مرحلهٔ اشکالزدایی استفاده نکنید.
تمرینهای پیشنهادی
چند ایده برای تمرین با try و except:
- برنامهای بنویسید که:
- از کاربر دو عدد بگیرد،
- آنها را تقسیم کند،
- اگر عدد نبود → پیام مناسب بدهد،
- اگر تقسیم بر صفر بود → پیام مناسب دیگری بدهد.
- برنامهای بنویسید که:
- نام فایلی را از کاربر بگیرد،
- محتویات آن را بخواند و چاپ کند،
- اگر فایل نبود → پیام خطای مناسب نشان دهد،
- از
elseوfinallyهم استفاده کنید. - برنامهای بنویسید که:
- چند بار از کاربر نمره (۰ تا ۲۰) بگیرد تا ورودی درست بدهد،
- برای ورودی غلط (عدد نبودن، منفی بودن، بالاتر از ۲۰) از
try/exceptو شرطها استفاده کند، - در نهایت نمرهٔ معتبر را چاپ کند.
با تمرین در این الگوها، بهتدریج استفاده از try و except برایتان طبیعی میشود و میتوانید برنامههایی بنویسید که هم «محکمتر» باشند، هم پیامهای خطای مناسبتر به کاربر نشان بدهند.