سپتامبر 13, 2019 Mostafa بدون دیدگاه

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

توجه : درخواست افزونه ،قالب، اسکریپت و نرم افزار و ... و سوالات و مشکلات خود را در انجمن ارسال نمایید

بعضی اوقات خطای در طول اجرای برنامه رخ میده. مثلا وقتی از فایلی بخوایم استفاده کنیم یا ورودی از کاربر بگیریم، ممکنه مثلا فایل مورد نظر وجود نداشته باشه یا جابجا شده باشه. یا اینکه کاربر هر چیزی وارد کنه. یه برنامه نویس قوی سعی میکنه یه سری محافظ برای برنامش درست کنه که توی شرایط مختلف برنامه از کار نیوفته. خود شما برنامه ای رو استفاده میکنین که هر چند وقت از کار میوفته و ارور میده؟

اگر ما بتونیم تشخیص بدیم که کدوم قسمت برناممون ممکنه ارور بده، میتونیم به پایتون بگیم که حواست به این قسمت باشه، اگر اروری پیش اومد، یه کار خاص کن ولی برنامه رو متوقف نکن.

باید بگم که تمام خطای های در طول اجرای برنامه و خطاهای نوشتاری جزو استثنا (exception) در پایتون هستن و باید یه جوری مشکل اونارو حل کرد (handle).

یکی از راه های حل این مشکل، استفاده از بلوک کد try-except هستش. کد زیر رو ببینید:

try:
    age = int(input("Lotfan senne khod ra vared konid: "))
    print("Shoma %d saletan ast" % age)

except ValueError:
    print("Lotfan adad vared konid na chizaye dige!")

توی کد بالا، پایتون میاد کدهای توی بلوک try رو اجرا میکنه. اگر هر جایی خطای مقدار یا همون ValueError رخ بده، دستورات try از همونجا متوقف میشه و میره بلوک except رو اجرا میکنه. همونطور که توی کد میتونید بخونید، یکی از جاهایی که این خطا رخ میده وقتیه که به جای عدد، یه چیزی مثل رشته وارد کنیم. اینجاست که چون تابع ()int تبدیل رشته به عدد رو انجام میده، میبینه که رشته شامل عدد نیست و خطا میده. پس پایتون میره سراغ کدهای except.

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

try:
    age = int(input("Lotfan senne khod ra vared konid: "))
    print("Shoma %d saletan ast" % age)

except Exception as e:
    print(e)

کد بالا میاد کل کلاس Exception رو لود میکنه و هر اروری بده پرینت میکنه. این کار اما بدی های خودش رو داره. فرض کنید توی خونتون فقط قرض سردرد دارید. هر مشکلی پیش بیاد، از جمله دل درد، سر درد، خون ریزی معده و … فقط و فقط میتونید از همون یه قرص استفاده کنید. خب معلومه خیلی کارساز نیست و حتی گاهی اوقات ممکنه وضعیت رو وخیم ترم کنه. استفاده از این روش کلی هم خیلی خوب نیست. پس تا جایی که میتونید سعی کنید مدیریت خطای جزئی تری داشته باشید تا برنامتون با کیفیت تر بشه.

میشه چندتا خطا رو توی یک بلاک تعریف کرد:

try:
    age = int(input("Lotfan senne khod ra vared konid: "))
    print("Shoma %d saletan ast" % age)

except(ValueError, ZeroDivisionError):
    print("Oops, ye chizi eshtebahe!")

یا اینکه برای یک try، چند تا except گذاشت:

try:
    age = int(input("Lotfan senne khod ra vared konid: "))
    print("Shoma %d saletan ast" % age)

except(ValueError):
    print("Oops, ye chizi eshtebahe!")

except(ZeroDivisionError):
    print("Oops, taghsim be sefr k nmsihe!")

این قسمت هم اختیاریه ولی پیشنهاد میکنم نگاهی بهش بندازین که جالبه. توی این قسمت میخوایم از کاربر بخوایم یه عدد وارد کنه. هر چیزی که وارد کنه، ما چک میکنیم که عدده یا خیر. اگر عدد نبود اینقدر این کار تکرار میشه تا بالاخره کاربر یه عدد وارد کنه. البته این کار رو با دو تا روش انجام میدیم. یه روش با استفاده از if و یکی دیگه با مدیریت خطا.

کد زیر روش if رو نشون میده:

n = None
while n is None:
    s = input("Lotfan yek adad vared konid: ")
    if s.lstrip('-').isdigit():
        n = int(s)
    else:
        print("%s yek adad nist." % s)

کد بالا از کاربر برای ورودی سوال میکنه. اون دستور if میاد بررسی میکنه اول اگر عدد علامت منفی ('-') داشته باشه، با استفاده از تابع ()lstrip اون رو حذف میکنه و بعدش با استفاده از تابع ()isdigit بررسی میکنه که آیا عدده یا خیر. تا زمانی که مقدار n یه عدد نباشه، این حلقه ادامه پیدا میکنه.

کد زیر روش مدیریت خطا رو نشون میده:

n = None
while n is None:
    try:
        s = input("Lotfan yek adad vared konid: ")
        n = int(s)
    except ValueError:
        print("%s yek adad nist." % s)

کد بالا از کاربر برای ورودی سوال میکنه. فرض میکنه عدد وارد کرده کاربر و اون رو توی n میذاره. اگر واقعا عدد باشه، تابع ()int اون رشته عددی رو به عدد واقعی تبدیل میکنه و توی n میذاره. اگر هم کاربر عدد وارد نکرده باشه، ValueError رخ میده و دوباره این حلقه تکرار میشه تا n مقدارش واقعا یک عدد بشه.