اخیراً مدیرم به من دستور داد تا یک گزارش خودکار ایجاد کنم. من گزارش را ساده طراحی کردم. این شامل تعدادی اعداد از یک پایگاه داده و برخی از عملیات های ریاضی پایه بود. هیجان زده بودم که بالاخره توانستم خودم را به رخ بکشم حیرت آور مهارت های پایتون برای شرکت.

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

داستان کوتاه من جزئیاتی ندارد، اما باید اهمیت رسیدگی به موارد لبه و خطاها را هنگام نوشتن برنامه ها برجسته کند. این گزارش باید فرصتی برای نشان دادن قدرت پایتون من باشد. با این حال، به یک پاییز شرم آور تبدیل شد-روی-لحظه صورت من

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

قبل از شروع به کار با استثناها، باید درک خوبی از اصول پایتون داشته باشید. شما باید بدانید که چرا استثناها برای مقابله با آنها پرتاب می شوند!

در اینجا چیزی است که ما پوشش خواهیم داد:

  1. دستورات را در پایتون امتحان کنید
  2. اعدام مشروط با بند دیگر
  3. استثناهای داخلی
  4. استثناهای سفارشی
  5. ملاحظات عملکرد

دستورات را در پایتون امتحان کنید

این try و except عبارات روش اصلی برخورد با استثناها هستند. آنها چیزی شبیه به این هستند:

x = 0
try:
    print(5 / x)
except ZeroDivisionError:
    print("Something went wrong")
    
# Something went wrong

بیایید کد بالا را بررسی کنیم تا هستیم روی همان page:

  1. خط 1 مقدار 0 را به یک متغیر اختصاص می دهد x
  2. خطوط 2 و 3 a را باز می کنند try بند و سعی کنید 5 را بر متغیر تقسیم کنید x
  3. خطوط 4 و 5 یک را باز می کنند except بند برای هر ZeroDivisionError و به برنامه دستور دهید print یک پیام باید سعی کنیم هر چیزی را بر 0 تقسیم کنیم

احتمالا متوجه موضوع شده اید. متغیر من x مقدار 0 را دارد و من سعی می کنم 5 را بر تقسیم کنم x. بهترین ریاضیدانان جهان نمی توانند بر 0 تقسیم کنند و پایتون نیز نمی تواند. بنابراین، چه اتفاقی می افتد؟

اگر خطا را کنترل نکنیم، برنامه بلافاصله پس از تلاش برای تقسیم 5 بر خاتمه می یابد x. از آنجایی که برنامه‌ها نمی‌دانند بدون دستورالعمل‌های صریح با استثناها چه کنند، ما آن را ایجاد کردیم except عبارت روی خط 4 و مراحلی را که برنامه در صورت تقسیم چیزی بر 0 باید طی کند را ارائه کرد.

این کل ایده پشت مدیریت استثناهاست: شما باید به برنامه بگویید وقتی خطایی دارد که به سادگی نمی تواند نادیده بگیرد چه کاری انجام دهد. بیایید نگاه کنیم که چگونه try و except بندها کار می کنند

شکستن بیانیه امتحان

Try و Except عبارات از الگویی پیروی می کنند که به شما امکان می دهد مشکلات موجود در کد خود را به طور قابل اعتماد مدیریت کنید. بیایید الگو را مرور کنیم.

اولین مرحله ای که اتفاق می افتد، کد موجود در آن است try بند تلاش می کند تا اجرا شود.

پس از آن، ما سه احتمال داریم:

هیچ خطایی در بند امتحان وجود ندارد

اگر کد در try بند اجرا می شود بدون هیچ خطایی، برنامه:

  1. را اجرا کنید try عبارت
  2. رد شدن از همه except بندها
  3. به طور معمول به دویدن ادامه دهید
x = 1
try:
    print(5 / x)
except ZeroDivisionError:
    print("Something went wrong")

print("I am executing after the try clause!")

# 5.0
# I am executing after the try clause!

می بینید که در این مثال اصلاح شده، هیچ مشکلی در آن وجود ندارد try بند (خط 3 و 4). کد اجرا خواهد شد، except بند نادیده گرفته می شود و برنامه پس از پایان اجرا مجدداً اجرا می شود try و except بیانیه ها نتیجه می گیرند

پیشنهاد می‌کنیم بخوانید:  بررسی کنید که آیا یک رشته حاوی عنصری از یک لیست در پایتون است یا خیر

خطاها در Try Clause و Exception مشخص شده است

اگر کد در try عبارت استثنا می اندازد و نوع استثنا بعد از هر کدام مشخص می شود except کلمه کلیدی، برنامه:

  1. از کد باقی مانده در try عبارت
  2. هر کدی را در تطبیق اجرا کنید except عبارت
  3. به طور معمول به دویدن ادامه دهید
x = 0
try:
    print(5 / x)
except:
    print("Something went wrong")
    
print("I am executing after the try clause!")

# Something went wrong
# I am executing after the try clause!

بازگشت به مثال اول، من متغیر خود را تغییر دادم x به مقدار 0 برگشت و سعی کرد 5 را بر تقسیم کند x. این تولید یک ZeroDivisionError. از زمانی که من except بیانیه این نوع استثنا را مشخص می کند، کد موجود در آن بند قبل از شروع مجدد برنامه به صورت عادی اجرا می شود.

خطاها در بند امتحان و استثنا مشخص نشده است

در نهایت، اگر برنامه یک استثنا را در try عبارت، اما استثنا در هیچ کدام مشخص نشده است except بیانیه، سپس برنامه این کار را انجام می دهد:

  1. اجرای برنامه را متوقف کنید و خطا را پرتاب کنید
x = 0
try:
    print(5 / y)
except:
    print("Something went wrong")

print("I am executing after the try clause!")

# NameError: name 'y' is not defined

در مثال بالا، من سعی می کنم 5 را بر متغیر تقسیم کنم y، که وجود ندارد. این امر الف را بالا می برد NameError. من به برنامه مشخص نمی کنم که چگونه باید آن را مدیریت کند NameErrors، بنابراین تنها گزینه این است که خود را خاتمه دهد.

تمیز کردن

Try و except ابزارهای اصلی در رسیدگی به خطاها هستند، اما یک بند اختیاری که می توانید از آن استفاده کنید نامگذاری شده است finally. این finally بند همیشه اجرا می شود، چه خطایی وجود داشته باشد یا نه.

x = 0
try:
    print(5 / x)
except ZeroDivisionError:
    print("I am the except clause!")
finally:
    print("I am the finally clause!")

print("I am executing after the try clause!")

# I am the except clause!
# I am the finally clause!
# I am executing after the try clause!

در این مثال، من مورد علاقه خود را ایجاد کرده ام ZeroDivisionError. می بینید که ترتیب اجرا به این صورت است:

  1. این except عبارت
  2. این finally عبارت
  3. هر کدی بعد از آن

هنگامی که ما تعمیر try بند برای اینکه دیگر خطا ایجاد نشود، همچنان ترتیب اجرای مشابهی را خواهید دید. به جای except بند در حال اجرا، try بند اجرا خواهد شد.

x = 1
try:
    print(5 / x)
except ZeroDivisionError:
    print("I am the except clause!")
finally:
    print("I am the finally clause!")

print("I am executing after the try clause!")

# 5.0
# I am the finally clause!
# I am executing after the try clause!

متوجه خواهید شد که تنها تفاوت این است try بند با موفقیت اجرا شد زیرا هیچ استثنایی وجود ندارد. این finally بند و کد پس از آن همانطور که انتظار دارید اجرا شود.

این برای برخی موارد مفید است که می‌خواهید بدون توجه به نتیجه کار خود را تمیز کنید try و except بندها اقداماتی مانند بستن اتصالات، بستن فایل‌ها و ثبت نام، کاندیدای عالی برای این کار هستند finally عبارت.

اعدام مشروط با بند دیگر

بند اختیاری دیگر عبارت است از else عبارت. این else بند ساده است: اگر کد در try بند بدون ایجاد خطا اجرا می شود، سپس کد در else بند نیز اجرا خواهد شد.

x = 1
try:
    print(5 / x)
except ZeroDivisionError:
    print("I am the except clause!")
else:
    print("I am the else clause!")
finally:
    print("I am the finally clause!")

print("I am executing after the try clause!")

# 5.0
# I am the else clause!
# I am the finally clause!
# I am executing after the try clause!

ترتیب اجرای این مثال به صورت زیر است:

  1. این try عبارت
  2. این else عبارت
  3. این finally عبارت
  4. هر کدی بعد از آن
پیشنهاد می‌کنیم بخوانید:  ارسال Props به this.props.children در ReactJS

اگر قرار بود استثنا یا خطایی را در آن تجربه کنیم try بند، else بند نادیده گرفته می شود.

x = 0
try:
    print(5 / x)
except ZeroDivisionError:
    print("I am the except clause!")
else:
    print("I am the else clause!")
finally:
    print("I am the finally clause!")

print("I am executing after the try clause!")

# I am the except clause!
# I am the finally clause!
# I am executing after the try clause!

استثناهای داخلی

تا به حال دیده اید که من در مورد دو استثنا با نام متفاوت نوشته ام: NameError و ZeroDivisionError. اگر به استثناهای دیگری نیاز داشته باشم چه می‌شود؟

لیست کاملی از استثناهای پایتون وجود دارد که با کتابخانه استاندارد ارائه می شود. اینها احتمالاً تقریباً با هر نیازی که در رسیدگی به هرگونه خطا یا استثنا دارید مطابقت دارند.

در اینجا فقط چند مورد است که ممکن است مهم باشد:

  • KeyError – یک کلید در فرهنگ لغت یافت نمی شود
  • IndexError – شاخص خارج از محدوده است روی یک شیء تکرارپذیر
  • TypeError – یک تابع یا عملیات استفاده شده است روی نوع اشتباه شی
  • OSError – خطاهای عمومی سیستم عامل

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

استثناهای سفارشی

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

class ForError(Exception):
    def __init__(self, message):
        self.message = message
    
    def foo(self):
        print("bar")

در مثال بالا، یک کلاس جدید ایجاد می کنم و آن را از کلاس Exception گسترش می دهم. اکنون، می توانم عملکرد سفارشی بنویسم و ​​با این استثنا مانند هر شی دیگری رفتار کنم.

try:
    raise FooError("This is a test error")
except FooError as e:
    e.foo()

# bar

در اینجا، من جدید خود را مطرح می کنم FooError روی هدف من میگیرم FooError و به آن نام مستعار بدهید e. اکنون، من می توانم به من دسترسی داشته باشم foo() متدی که من در کلاسی که ایجاد کردم ساخته ام.

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

ملاحظات عملکرد

حالا که اصول اولیه را فهمیدید try، exceptو اشیاء استثنایی، می توانید شروع به استفاده از آنها در کد خود کنید تا به خوبی خطاها را مدیریت کنید. آیا تأثیرات قابل توجهی بر عملکرد کد وجود دارد؟

جواب کوتاه، نه است. با انتشار Python 3.11، عملاً هیچ کاهش سرعتی از استفاده وجود ندارد try و except عباراتی که هیچ استثنایی وجود ندارد.

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

در نسخه های قبلی پایتون، با استفاده از try و except بندها باعث ایجاد زمان اضافی برای اجرا شد. اگر به روز نیستید این را در نظر داشته باشید.

برای جمع بندی

ممنون که تا اینجا خوندید خود و مشتریان آینده شما از شما برای رسیدگی به خطا تشکر خواهند کرد.

رفتیم بالای try، except، else، و finally بندها و حکم اجرای آنها و در چه شرایطی اجرا می شوند. ما همچنین اصول ایجاد استثناهای سفارشی را بررسی کردیم.

مهمترین چیزی که باید به خاطر بسپارید این است که try و except بندها راه های اصلی برای کشف خطاها هستند و هر زمان که کد خطرناک و مستعد خطا دارید باید از آنها استفاده کنید.

همچنین به خاطر داشته باشید که گرفتن خطاها کد شما را انعطاف‌پذیرتر می‌کند و باعث می‌شود کدنویس بهتری به نظر برسید.