برنامه های پایتونی به محض اینکه به یک ارور برخورد کنند متوقف خواهند شد. در پایتون، ارورها میتوانند یک syntax error یا یک exception باشند. در این مقاله یاد میگیرید که یک exception چیست و تفاوت آن با syntax error چیست. پس از آن میفهمید که چطور باید یک exception را ایجاد کرده و با بلوک try/except خطاها را مدیریت کنید.
فرض کنید که میخواهید به عنوان ورودی از کاربر تاریخ تولد او را بگیرید تا بتوانید سن کاربر را محاسبه کنید. کاربر به جای عدد از حروف استفاده میکند. در اینصورت برنامه شما در زمان انجام محاسبات ریاضی با یک خطا یا exception مواجه خواهد شد. برای پیشگیری از این نوع مشکلات باید از مدیریت خطا در پایتون یا Exception Handling استفاده کنید.
# exception چیست؟
exception یا استثنا نوعی از مشکلات منطقی هستند که ممکن است در حین اجرای برنامه رخ دهند. برنامه نویس باید به طور صحیح این خطاها را مدیریت کند. exception ها در پایتون با استفاده از کلمه کلیدی try کنترل میشوند. به شکلی که قطعه کدی که ممکن است باعث ایجاد خطا شود را در بلاک try قرار داده و کدی که در زمان اجرا خطا باید اجرا شود در بلاک except. اگر خطا بروز ندهد بلاک except رد شده و اجرا نخواهد شد. تمام exceptionها باید کنترل شوند و اگر در حین اجرای برنامه exception اتفاق بیفتد که کنترل نشده، برنامه به طور کامل متوقف خواهد شد.
پایتون تعداد زیادی exception داخلی دارد که ممکن است در زمان مشکل نمایش داده شوند. هنگامی که یک exception رخ میدهد، مفسر پایتون فرآیند فعلی را متوقف کرده و خطا را به اجرا کننده کد ارسال میکند. اگر خطا به درستی مدیریت نشود، برنامه متوقف خواهد شد.
+ تفاوت exception و syntax error
خطاهای نحوی زمانی رخ می دهد که مفسر پایتون یک دستور نادرست را تشخیص دهد. به مثال زیر توجه کنید:
>>> print( 0 / 0 ))
File "<stdin>", line 1
print( 0 / 0 ))
^
SyntaxError: invalid syntax
علامت فلش نشان می دهد که مفسر پایتون در کجا با خطای سینتکس مواجه شده است. در این مثال، یک پرانتز اضافی بود. آن را حذف کنید و دوباره کد خود را اجرا کنید:
>>> print( 0 / 0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
این بار با یک exception مواجه شدید. این نوع خطا زمانی رخ می دهد که کد پایتون از نظر سینتکس درست بوده اما به یک ارور منطقی برخورد میکند. خط آخر پیام نشان می دهد که با چه نوع خطای استثنا مواجه شده اید. مفسر پایتون با استثناهای مختلف به درک بهتر از نوع خطا به ما کمک میکند.
# مدیریت خطا در پایتون با try و except و finally
در پایتون دو روش برای مدیریت خطا وجود دارد:
- Exception Handling
- Assertion
در این مقاله ما روی مورد اول تمرکز میکنیم. اگر دوست دارید با مورد دوم هم آشنا شوید پیشنهاد میکنیم ویدیو آموزش assertion در پایتون را ببینید. برای مدیریت استثناها در پایتون میتوانید از سه کلمه کلیدی try و except و finally استفاده کنید که در ادامه به توضیح این موارد میپردازیم.
+ دستورهای try و except برای مدیریت استثنا
دستورهای try و except برای گرفتن و مدیریت خطا در پایتون استفاده میشود. اگر کد مشکوکی دارید که ممکن است استثنا ایجاد کند، می توانید با قرار دادن کد مشکوک در بلاک try از برنامه خود محافظت کنید. بعد از بلاک try یک بلاک except خواهد بود که مشخص میکند در زمان خطا چه اتفاقی بیفتد. بلاک های except مشخص میکنند که برنامه در زمان بروز خطا چطور واکنش دهد. میتوانید یک یا چند بلاک except برای یک try داشته باشید. دقت کنید که وجود حداقل یک بلاک except برای هر try اجباری است.
حالت کلی مدیریت استثنا در پایتون به شکل زیر است:
try:
You do your operations here;
......................
except Exception1:
If there is Exception1, then execute this block.
except Exception2:
If there is Exception2, then execute this block.
......................
else:
If there is no exception then execute this block.
مفسر پایتون کدی که در بلاک try وجود دارد را به شکل کاملا عادی اجرا خواهد کرد. اگر این کد بدون خطا اجرا شود، هیچ یک از بلاک های except اجرا نخواهند شد. اما اگر کد try باعث بروز خطا شود یکی از بلاک های except فعال خواهد شد. اگر هیچ یک از بلاک های except نتوانند خطای ایجاد شده را مدیریت کنند، در نهایت فارق از نوع خطا، بلاک else اجرا خواهد شد.
در کد پایین یک فایل باز کرده و داخل آن چیزی مینویسیم. بخشی از کد که ممکن است ارور دهد را داخل بلاک try نوشتهایم. از آنجایی که کد ما مشکلی ندارد، اگر کد را اجرا کنیم بلاک try بدون ارور اجرا خواهد شد و بخشهای except اجرا نخواهد شد. بخش else در صورتی که کد بدون مشکل کار کند، اجرا خواهد شد:
try:
fh = open("testfile", "w")
fh.write("This is my test file for exception handling!!")
except IOError:
print "Error: can\'t find file or read data"
else:
print "Written content in the file successfully"
fh.close()
# OUTPUT
Written content in the file successfully
در مثال دوم سعی میکنیم در فایلی بنویسیم که اجازه نداریم. به همین خاطر بخش try ارور داده و بخش except اجرا خواهد شد:
try:
fh = open("testfile", "r")
fh.write("This is my test file for exception handling!!")
except IOError:
print "Error: can\'t find file or read data"
else:
print "Written content in the file successfully"
# OUTPUT
Error: can't find file or read data
+ دستور finally برای مدیریت خطای رخ داده در پایتون
یکی دیگر از دستوراتی که میتوانید در مدیریت خطا استفاده کنید دستور finally است. دستور finally اختیاری بوده و همیشه اجرا خواهد شد، مهم نیست که خطا رخ داده باشد یا خیر. دقت کنید که برای هر بلاک try فقط میتوانید یک بلاک finally داشته باشید.
به مثال زیر دقت کنید:
try:
linux_interaction()
except AssertionError as error:
print(error)
else:
try:
with open('file.log') as file:
read_data = file.read()
except FileNotFoundError as fnf_error:
print(fnf_error)
finally:
print('Cleaning up, irrespective of any exceptions.')
اگر کد بالا را اجرا کنید بخش finally حتما اجرا خواهد شد بدون توجه به اینکه ارور رخ داده یا خیر. اگر کد بالا را اجرا کنید نتیجه به شکل زیر خواهد بود:
Function can only run on Linux systems.
Cleaning up, irrespective of any exceptions.
+ raise در پایتون
گاهی اوقات نیاز دارید تا در شرایطی خاص خودتان یک استثنا را نمایش دهید. در این حالت میتوانید از کلمه کلیدی raise پایتون استفاده کنید. همچنین میتوانید یک پیغام هم ارسال کنید تا توضیح مختصری درمورد exception هم داده باشید.
x = 10
if x > 5:
raise Exception('x should not exceed 5. The value of x was: {}'.format(x))
در قطعه کد بالا اگر عدد x بزرگتر از 5 باشد یک خطا نمایش میدهیم.
# انواع خطا در پایتون
رایج ترین دلیل خطا در برنامه های پایتونی زمانی است که یک دستور خاص به درستی استفاده نشده باشد. در این حالت با خطای Syntax Error یا خطای نحوی در پایتون مواجه خواهید شد. در قسمت قبل نمونه ای از این نوع خطا را دیدیم.
اما در بسیاری از اوقات، با وجود اینکه هیچ خطای نحوی ندارید باز هم پایتون به شما پیغام خطا نمایش میدهد. به این نوع پیغام ها، خطای زمان اجرا(runtime error) گفته میشود که معمولا مفسر پایتون آن را با یک استثنا نمایش میدهد. بیایید با هم چند نمونه از این استثناها را ببینیم.
در لیست زیر، مهم ترین exception های پایتون آورده شده اند:
نوع استثنا | دلیل ایجاد شدن خطا |
---|---|
AssertionError | اگر شرط بررسی شده با assert درست نباشد. برای اطلاعات بیشتر ویدیو آموزش assert در پایتون را ببینید |
AttributeError | اگر ویژگی درخواست شده وجود نداشته باشد |
EOFError | اگر مشکلی در پایان فایل وجود داشته باشد. برای اطلاعات بیشتر پیغام خطای EOF در پایتون را ببینید |
FloatingPointError | اگر عملیات انجام شده روی نوع داده float به مشکل بخورد |
GeneratorExit | اگر متد close روی یک جنریتور صدا زده شود. برای اطلاعات بیشتر ویدیو آموزش generator در پایتون را ببینید |
ImportError | اگر ماژول ایمپورت شده پیدا نشود |
IndexError | اگر ایندکس درخواست شده در دنباله وجود نداشته باشد |
KeyError | اگر کلید درخواست شده در دیکشنری وجود نداشته باشد |
KeyboardInterrupt | اگر کاربر دکمه ctrl+c یا delete را بزند |
MemoryError | اگر پردازش در حال اجرا با کمبود حافظه مواجه شود |
NameError | اگر متغیر خواسته شده در محدوده محلی یا جهانی پیدا نشود. برای اطلاعات بیشتر ویدیو آموزش scope در پایتون را ببینید |
NotImplementedError | اگر متد انتزاعی ایجاد نشده باشد. برای اطلاعات بیشتر ویدیو آموزش abstract در پایتون را ببینید |
OSError | اگر یک عملیات سیستم باعث خطا در سیستم عامل شود |
OverflowError | اگر نتیجه یک عملیات حسابی بیش از حد بزرگ باشد که قابل نمایش نباشد |
RuntimeError | اگر خطای ایجاد شده در هیچ یک از دسته بندی ها قرار نگیرد |
StopIteration | اگر متد next به انتهای یک دنباله برسد |
SyntaxError | اگر مفسر با یک خطای نحوی مواجه شود |
IndentationError | اگر مشکلی در تورفتگی وجود داشته باشد. برای اطلاعات بیشتر درک کامل تورفتگی در پایتون را ببینید. |
TabError | هنگامی که تورفتگی از tab ها و فاصله های ناسازگار تشکیل شده باشد |
SystemError | زمانی که مفسر با یک مشکل داخلی مواجه شود |
SystemExit | این استثنا توسط تابع sys.exit ایجاد میشود |
TypeError | اگر نوع آبجکت انتخاب شده برای عملیات نامناسب باشد |
ValueError | اگر فانکشن آرگومانی با نوع درست اما مقدار اشتباه دریافت کند |
ZeroDivisionError | اگر عملیات تقسیم روی عدد صفر انجام شود |
# ساخت یک استثنا جدید در پایتون
در این بخش یاد میگیرید که چطور یک exception جدید ایجاد کنید. همانطور که تا اینجا دیدید، پایتون دارای تعداد زیادی استثنا است که در صورت بروز خطا از آنها استفاده میشود. اما استثناهای داخلی پایتون همیشه نمیتوانند نیازهای ما را پاسخ دهند.
در پایتون تمام استثناهای داخلی از کلاس Exception ارثبری میکنند. شما هم اگر بخواهید یک استثنا جدید بسازید باید کلاسی داشته باشید که مستقیم یا غیر مستقیم از این کلاس ارثبری کند:
>>> class CustomError(Exception):
... pass
...
>>> raise CustomError
Traceback (most recent call last):
...
__main__.CustomError
>>> raise CustomError("An error occurred")
Traceback (most recent call last):
...
__main__.CustomError: An error occurred
در قطعه کد بالا، یک کلاس به نام CustomError ساختیم که از کلاس Exception ارثبری میکند. این استثنا جدید میتواند مانند دیگر استثناهای پایتون با raise نمایش داده شود.
زمانیکه در حال توسعه یک پروژه بزرگ پایتونی هستید، بهتر است که تمام استثناها را در یک فایل جداگانه قرار دهیم. این فایل ها معمولا exceptions.py یا errors.py نام دارند.
# نتیجه گیری: مدیریت خطا در پایتون
بعد از یاد گرفتن اینکه exception یا استثنا چیست و تفاوت آن سینتکس ارور، روش های مختلف برای مدیریت خطای رخ داده را دیدید:
- دستور raise برای نمایش یک استثنا استفاده میشود.
- عبارت try، تمام دستورات را تا زمانی که با یک استثنا مواجه شوید اجرا می کند.
- دستور except برای گرفتن و کنترل کردن استثناها استفاده میشود.
- دستور else زمانی فعال میشود که هیچ یک از except ها نتوانند خطا را مدیریت کنند.
- دستور finally که همیشه اجرا میشود
ارسال نظر