مدیریت خطا با try و except در پایتون

May 2022


برنامه های پایتونی به محض اینکه به یک ارور برخورد کنند متوقف خواهند شد. در پایتون، ارورها میتوانند یک 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

در پایتون دو روش برای مدیریت خطا وجود دارد:

  1. Exception Handling
  2. 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 یا استثنا چیست و تفاوت آن سینتکس ارور، روش های مختلف برای مدیریت خطای رخ داده را دیدید:


5:47:36


0

Intro

10:38

رایگان

1

Variable

12:30

رایگان

2

String

19:22

رایگان

3

List

8:46

رایگان

4

While

9:6

رایگان

5

If

8:37

رایگان

6

For

6:12

رایگان

7

range

4:17

رایگان

8

break, continue, pass

9:15

رایگان

9

Function

12:32

رایگان

10

List methods

12:11

رایگان

11

Tuple

8:29

رایگان

12

Set

7:47

رایگان

13

Dictionary

9:19

رایگان

14

Module

10:40

رایگان

15

fstring

5:35

رایگان

16

format

7:34

رایگان

17

File

17:14

رایگان

18

Scope

6:25

رایگان

19

OOP

12:15

رایگان

20

Method

20:19

رایگان

21

class/instance variable

14:7

رایگان

22

class/static method

13:25

رایگان

23

Inheritance

17:6

رایگان

24

Special methods

9:50

رایگان

25

Access points

11:12

رایگان

26

property

6:54

رایگان

27

Exceptions

21:17

رایگان

28

Standard library

12:51

رایگان

29

Docstring

10:49

رایگان

30

Virtualenv

11:2

رایگان


دوره‌های پیشنهادی

دوره اول آموزش جنگو(django)

دوره اول آموزش جنگو(django)

دوره اول آموزش فلسک(Flask)

دوره اول آموزش فلسک(Flask)

دوره آموزش Design Patterns در پایتون

دوره آموزش Design Patterns در پایتون

ارسال نظر

تلاش میکنم سوالات شما را در کمتر از یک روز پاسخ بدم

Hasan afshari

December 2021

سلام و عرض ادب خدمت شما استاد عزیز، بنده در رابطه با access point ها به مشکل برخوردم.که در رابطه با نمایش اطلاعات private است که متاسفانه در برنامه من حالت printe(Person._Person__height) دچار خطا میشه و برای بنده به این شکل نمایش داده میشه که البته با اضافه پایتونی:

class Person:

def __init__(self, name, _age, __height):
self.__height = __height
self.name = name
self._age = _age

def info(self):
print("My name is " + self.name + "!\nAnd I'm " + str(self._age) + " years old!")

@property
def Person__height(self):
return self._Person__height

class Me(Person):
def info(self):
print("My info:")
super().info()

m = Me("Hasan", 22, 180)

m.info()
print(m.Person__height)

ارسال نظر


امیرحسین بیگدلو

December 2021

سلام
از کد و ارورت عکس بگیر برام بفرست

علی

May 2021

واقعا خسته نباشید. بسیار مختصر ومفید و به اندازه مطالب رو میگید.

ارسال نظر


afshin

July 2020

دمتون گرم خيلي خوووووووب توضيح دادين

ارسال نظر


امیرحسین بیگدلو

July 2020

چاکریم