مطلب آموزشی 3:
خطا ها در پایتون

خطاهای نحوی

خطاهای نحوی که به عنوان خطاهای زمان تجزیه هم شناخته مـیشـوند، شـاید متـداولتـرینخطاهایی باشند که شما با آن برخورد میکنید:

while 1 print “Hello world!” Traceback ( File “”, line 1 while 1 print “Hello world!” ^ SyntaxError: invalid synta

تجزیهگر (که قسمتی از مفسر است) خط نادرست را تکرار مـیکنـد و یـک پیکـان کوچـک در نزدیکترین نقطه به محل تشخیص خطا نمایش میدهد. توکنی که قبل از علامت پیکـان آمـده اسـت منجر به خطا شده است (یا لااقل خطا در آن شناخته شده است).

در مثال فوق، خطا در کلمـۀ کلیـدیprint تشخیص داده شده، چرا که علامـت کـولن (:) بعـد از دسـتور print از قلـم افتـاده اسـت. همچنین نام فایل و شماره خط در پیغام خطا چاپ شـده تـا در صـورتی کـه ورودی از یـک اسـکریپت می آید، شما بدانید در کجا به دنبال خطا بگردید.

اعتراض ها

حتی اگر دستور (یا عبارت) از لحاظ نحوی درست باشد، ممکن است وقتـی قصـد اجـرای آن را دارید منجر به خطا شود. خطاهایی که در طول اجرای برنامه رخ میدهند، اعتراض نامیـده مـیشـوند و مطلقاً خطاهای مهلکی نیستند. شما به زودی میآموزید که چگونه آنها را کنترل کنید. اغلب اعتراضات توسط برنامهها مدیریت نمیشوند (بـه هـر دلیـل) و پیغـام خطـایی را بـه ایـن صورت نتیجه میدهند:

>> 10 * (1/0) Traceback (most recent call last): File “”, line 1, in ? ZeroDivisionError: integer division or modulo by zero >>> 4 + Spam*3 Traceback (most recent call last): File “”, line 1, in ? NameError: name ‘Spam’ is not defined >>> ‘2’ + 2 Traceback (most recent call last): File “”, line 1, in ? TypeError: cannot concatenate ‘str’ and ‘int’ objects

خط آخر پیغام خطا مشخص میکند که چه اتفاقی افتاده است. اعتراضها انواع گوناگونی دارند که نوع آنها در قسمتی از پیغام چاپ میشود.

انواع ذکر شده در مثال فوق عبارتند از ZeroDivisionError ،NameError و TypeError .

رشـتهای کـه بـه عنوان نوع اعتراض چاپ شده، اسم پیشساختهای برای اعتراضی که رخ داده است، میباشد.

ایـن نحـوهدر مورد تمام اعتراضهای پیشساخته صحیح است، اما صحت آن در مورد اعتراضهـای کـاربر-تعریـف
لزومی ندارد (اگرچه قرارداد مفیدی است). اسامی اعتراضهای استاندارد شناسـههـای پـیشسـاختهای هستند که نوع و هویت خطا را مشخص میکنند (و نه کلمات کلیدی رزرو شده در زبان پایتون).

بقیۀ خط، جزئیاتی است که تفسیر و معنای آن بستگی به نوع اعتراض دارد.

قسمت قبلیِ پیغام خطا، زمینهای در مورد محل وقوع خطا به فـرم پـسیـابی یـک پشـته ارائـه میدهد. بهطور کلی این پسیابی پشتهای خطوط مبدأ برنامه را لیست، اگرچه خطـوط خوانـده شـده از ورودی استاندارد نمایش داده شده نمیشوند. مرجع کتابخانۀ پایتون، تمام اعتراضهای پیشساخته و معانی آنها را فهرست کرده است.

کنترل اعتراض ها

در پایتون، نوشتن برنامههایی که برخی از اعتراضها را کنترل کند، امکانپـذیر اسـت. بـه ایـن مثال نگاه کنید:
>>> while 1:
… try:
… x = int(raw_input(“Please enter a number: “))
… break
… except ValueError:
… print “Oops! That was no valid number. Try again…”

در این مثال تا زمانی که یک ورودی معتبر وارد شود، وارد کردن یک عدد از کـاربر درخواسـت میشود، اما اجازه میدهد که او (با استفاده از C+Ctrl یا هر چیـز دیگـری کـه سیسـتم عامـل آن را پشتیبانی میکند) برنامه را قطع کند. توجه کنید که یک وقفۀ تولید شده توسط کاربر بهوسـیلۀ تولیـد یک اعتراض KeyboardInterrupt علامت داده میشود. الگوی استفاده از دستور try بهصورت زیر است:

ابتدا بند try اجرا میشود (دستور(های) میان دو کلمۀ کلیدی try و except ( · اگر هیچ اعتراضی رخ ندهد بند except نادیـده مـیشـود و اجـرای دسـتور try پایـان مییابد.
اگر در طول اجرای بند try اعتراضی رخ ندهد مابقی بند رها میشـود، آنگـاه در صـورتی
که نوع آن با نام اعتراضی که پس از کلمۀ کلیدی except آمـده مطابقـت کنـد، بـاقی بنـد
except اجرا میشود و سپس اجرا از دستور بعدی try ادامه مییابد.

 اگر اعتراضی رخ دهد که با اعتراض نام برده شده در بند except مطابقت نکند، کنتـرل به دستورات try بیرونیتر انتقال مییابد و در صورتی که کنترلکننده دیگری وجود نداشـته باشد یک اعتراض کنترل نشده رخ داده و اجرا با پیغامی (که نمونۀ آن را در بالا دیدید) متوقف میگردد. یک دستور try ممکن است به منظور کنترل و مدیریت اعتراضات گوناگون، بیش از یـک بنـد except داشته باشد اما تنها یکی از چند بند موجود اجرا شـده خواهـد شـد. کنتـرلکننـدههـا تنهـا اعتراضی را کنترل میکنند که در بند try متناظرشان اتفـاق افتـاده باشـد، نـه در کنتـرل کننـدگان دیگری که در همان دستور try قرار دارند. یک بند except ممکن است چندین اعتراض را در قالب یک لیست پرانتزگذاری شده عنـوان کند. برای مثال:
… except ValueError:
… pass
اگر نامهای اعتراض در مقابل دستور except حذف شوند، ایـن بنـد except بـرای تمـامی اعتراضها عمل میکند. بنابراین از این خصوصیت با احتیاط بسیار زیادی استفاده کنید. زیرا ایـن روش بهراحتی یک خطای واقعی برنامه نویسی را پنهان میکند. این دستور میتواند به منظور چاپ یک پیغام خطا و تولید مجدد اعتراض نیز به کار برده شود:
import string, sys
try:
f = open(‘myfile.txt’)
s = f.readline()
i = int(string.strip(s))
except IOError, (errno, strerror):
print “I/O error(%s): %s” % (errno, strerror)
except ValueError:print “Could not convert data to an integer.”
except:
print “Unexpected error:”, sys.exc_info()[0]
raise

دستور except…try میتواند یک بنـد else اختیـاری هـم داشـته باشـد کـه در صـورت استفاده از آن باید پس از تمام بندهای except قرار گیرد. این امکان، برای کدهایی که در عدم وقـوع اعتراض باید اجرا شوند، مفید است. برای مثال:

for arg in sys.argv[1:]:
try:
f = open(arg, ‘r’)
except IOError:
print ‘cannot open’, arg
else:
print arg, ‘has’, len(f.readlines()), ‘lines’
f.close()
استفاده از else بهتر از افزودن کدهای اضافی به قسمت try است، زیرا بـهطـور تصـادفی از تولید یک اعتراض جلـوگیری مـیکنـد. اعتراضـی کـه توسـط کـد محافظـت شـده بـهوسـیلۀ دسـتور except…try تولید نشده است. هنگامیکه یک اعتراض رخ میدهد، ممکن است مقدار وابستهای هم داشته باشد که این مقـدار با نام آرگومان اعتراض هم شناخته میشود. وقوع و نوع آرگومان به نوع اعتراض بستگی دارد. برای انواع اعتراضاتی که یک آرگومان دارند، ممکن است عبارت except متغیری پس از نام (یا لیست) اعتـراض داشته باشد تا مقدار آرگومان را دریافت کند. مانند:

> try:
… spam()
… except NameError, x:
… print x

name ‘spam’ is not defined

اگر اعتراضی یک آرگومان داشت، این آرگومان به عنوان قسمت آخـر (جزئیـات) پیغـام اجـرای اعتراض کنترل نشده چاپ میشود. کنترلکنندههای اعتراض تنها اعتراضاتی را که در قسمت try رخ دادهاند کنترل نمیکنند، بلکه اگر اعتراضاتی درون توابعِ فراخوانده شـده توسـط دسـتور try هـم رخ داده دهد کنترل مینمایند. برای مثال:

>> def this_fails():
… x = 1/0

>>> try:
… this_fails()
… except ZeroDivisionError, detail:
… print ‘Handling run-time error:’, detail

Handling run-time error: integer division or modulo by zero

 منبع: http://basickade.com/programming-errors-in-python/

خطا ها در پایتون
دسته بندی شده در:        

1 دیدگاه در “خطا ها در پایتون

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *