برای اطمینان از اینکه بخشی از کد همیشه اجرا شود، صرفنظر از وقوع خطا یا استثنا، میتوانید از بلوک finally استفاده کنید. این بلوک در انتهای ساختار try/except قرار میگیرد و کد داخل آن همیشه پس از اجرای کدهای try و در صورت وجود، بلوکهای except اجرا خواهد شد.
try:
print("Hello")
print(1 / 0)
except ZeroDivisionError:
print("Divided by zero")
finally:
print("This code will run no matter what")
خروجی:
Hello
Divided by zero
This code will run no matter what
کد داخل بلوک finally حتی اگر در بلوک except خطایی رخ دهد نیز اجرا میشود، مانند مثال زیر:
try:
print(1)
print(10 / 0)
except ZeroDivisionError:
print(unknown_var) # This will raise NameError
finally:
print("This is executed last")
خروجی:
1
This is executed last
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
NameError: name 'unknown_var' is not defined
علاوه بر try، except و finally، میتوانید از بلوک else نیز استفاده کنید. کد داخل else فقط زمانی اجرا میشود که در بلوک try هیچ استثنایی رخ ندهد.
ترتیب اجرای این بلوکها به شکل زیر است:
- try اجرا میشود.
- except مربوطه اجرا میشود و بلوک
elseنادیده گرفته میشود. در صورتی که خطایی باشد. - در زمانی که try بدون خطا اجرا شود سپس else اجرا میشود.
- و در آخر finally همیشه اجرا میشود، صرفنظر از وقوع خطا یا خیر.
نمونهای از استفاده از else همراه با سایر بلوکها:
try:
result = 10 / 2
except ZeroDivisionError:
print("Division by zero!")
else:
print(f"Result is {result}")
finally:
print("Execution completed.")
خروجی:
Result is 5.0
Execution completed.
گاهی نیاز دارید جزئیات خطا را بدانید، بلکه بخواهید از آن اطلاعات در برنامه استفاده کنید. در این صورت میتوانید از سینتکس except ExceptionType as e: استفاده کنید. این روش به شما امکان میدهد تا شیء استثنا را در یک متغیر ذخیره کرده و به اطلاعات آن دسترسی پیدا کنید.
try:
result = 10 / 0
except ZeroDivisionError as e:
print(f"Exception: {e}")
print(f"Exception Type: {type(e).__name__}")
خروجی:
Exception: division by zero
Exception Type: ZeroDivisionError
دسترسی به پیام کامل خطا با traceback
برای نمایش کامل traceback خطا (همان اطلاعاتی که در خط فرمان میبینید)، میتوانید از ماژول traceback استفاده کنید:
import traceback
try:
result = 10 / 0
except ZeroDivisionError as e:
print("Full Exception:")
traceback.print_exc()
خروجی:
Full Exception:
Traceback (most recent call last):
File "example.py", line 4, in <module>
result = 10 / 0
ZeroDivisionError: division by zero
نکات مهم
- همیشه از انواع خاص خطا (
except ValueError as e:) قبل ازexcept Exception as e:استفاده کنید تا بتوانید هر نوع خطا را به درستی مدیریت کنید. - از
except:بدون نوع خطا خودداری کنید، زیرا حتی سیگنالهای سیستمی مثلKeyboardInterruptرا نیز catch میکند. - متغیر
eفقط در محدوده بلوکexceptقابل دسترسی است. - برای لاگگیری حرفهای، از
traceback.format_exc()استفاده کنید تا رشته فرمتشده traceback را دریافت کنید.