مدیریت خطا در پایتون – امتحان کنید، به جز، else، و در نهایت با مثال کد توضیح داده شود
اخیراً، مدیرم به من دستور داد تا یک گزارش خودکار ایجاد کنم. من گزارش را ساده طراحی کردم. این شامل تعدادی اعداد از یک پایگاه داده و برخی از عملیات ریاضی پایه بود. من هیجان زده بودم که بالاخره توانستم مهارت های شگفت انگیز پایتون را به شرکت نشان دهم.
من تمام کردم و محصول را ارسال کردم. همه چیز عالی بود. حداقل تا حدود دو هفته بعد. گزارش من به طور تصادفی به دلیل خطای تقسیم بر صفر شروع به شکست کرد. نشانه آهنگ خنده.
داستان کوتاه من جزئیاتی ندارد، اما باید اهمیت رسیدگی به موارد لبه و خطاها را هنگام نوشتن برنامه ها برجسته کند. این گزارش باید فرصتی برای نشان دادن قدرت پایتون من باشد. با این حال، به یک لحظه خجالتآور تبدیل شد.
پس ، اجازه دهید چند لحظه به یادگیری اصول مدیریت خطا با استفاده از کتابخانه استاندارد پایتون بپردازیم. من قصد دارم برخی از چیزهایی را که برای شروع به آن نیاز دارید برجسته کنم.
قبل از شروع به کار با استثناها، باید درک خوبی از اصول پایتون داشته باشید. شما باید بدانید که چرا استثناها برای مقابله با آنها پرتاب می شوند!
در اینجا چیزی است که ما پوشش خواهیم داد:
دستورات را در پایتون امتحان کنید
دستورات try
و except
روش اصلی برخورد با استثناها هستند. آنها چیزی شبیه به این هستند:
x = 0 try: print(5 / x) except ZeroDivisionError: print("Something went wrong") # Something went wrong
بیایید کد بالا را مرور کنیم تا در همان صفحه باشیم:
خط 1 مقدار 0 را به متغیر x
اختصاص می دهد
خطوط 2 و 3 یک عبارت try
را باز می کنند و سعی می کنند 5 را بر متغیر x
تقسیم کنند
خطوط 4 و 5 یک عبارت except
را برای هر ZeroDivisionError
باز می کنند و به برنامه دستور می دهند که یک پیام را چاپ کند اگر سعی کنیم چیزی را بر 0 تقسیم کنیم.
احتمالا متوجه موضوع شده اید. متغیر x
من مقدار 0 را دارد و من سعی می کنم 5 را بر x
تقسیم کنم. بهترین ریاضیدانان جهان نمی توانند بر 0 تقسیم کنند و پایتون نیز نمی تواند. پس ، چه اتفاقی می افتد؟
اگر خطا را کنترل نکنیم، برنامه بلافاصله پس از تلاش برای تقسیم 5 بر x
خاتمه می یابد. از آنجایی که برنامهها نمیدانند بدون دستورالعملهای صریح با استثناها چه کنند، ما عبارت except
را در خط 4 ایجاد کردیم و مراحلی را برای برنامه در صورت تقسیم چیزی بر 0 ارائه کردیم.
این کل ایده پشت مدیریت استثناهاست: شما باید به برنامه بگویید که وقتی خطایی دارد که نمی تواند به سادگی نادیده بگیرد چه کاری انجام دهد. بیایید نگاه کنیم که چگونه بندهای try
و except
کار می کنند.
شکستن بیانیه امتحان
عبارات Try
و Except
از الگویی پیروی می کنند که به شما امکان می دهد مشکلات موجود در کد خود را به طور قابل اعتماد مدیریت کنید. بیایید الگو را مرور کنیم.
اولین مرحله ای که اتفاق می افتد این است که کد موجود در عبارت try
سعی می کند اجرا شود.
پس از آن، ما سه احتمال داریم:
دیگر اخبار
موزیلا به روشهای فریبنده مایکروسافت برای ترغیب کاربران به استفاده از مرورگر اج اعتراض کرد
هیچ خطایی در بند امتحان وجود ندارد
اگر کد موجود در عبارت try
بدون هیچ خطایی اجرا شود، برنامه:
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
مشخص شود ، برنامه:
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
ایجاد می کند. از آنجایی که دستور my except
این نوع استثنا را مشخص می کند، کد موجود در آن بند قبل از شروع مجدد برنامه به صورت عادی اجرا می شود.
خطاها در بند امتحان و استثنا مشخص نشده است
در نهایت، اگر برنامه یک استثنا در عبارت try
ایجاد کند، اما استثنا در هیچ عبارت except
مشخص نشده باشد ، برنامه این کار را انجام خواهد داد:
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
ایجاد می کند. من به برنامه مشخص نمی کنم که چگونه NameError
s را مدیریت کند، پس تنها گزینه این است که خودش را خاتمه دهد.
تمیز کردن
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
مورد علاقه خود را ایجاد کرده ام. می بینید که ترتیب اجرا به این صورت است:
بند except
بند finally
هر کدی پس از آن
هنگامی که بند 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!
ترتیب اجرای این مثال به صورت زیر است:
try
امتحان
بند else
بند finally
هر کدی پس از آن
اگر بخواهیم یک استثنا یا خطا در عبارت 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
راههای اصلی برای یافتن خطاها هستند و هر زمان که کد خطرناک و مستعد خطا دارید باید از آنها استفاده کنید.
همچنین، به خاطر داشته باشید که گرفتن خطاها کد شما را انعطافپذیرتر میکند و باعث میشود کدنویس بهتری به نظر برسید.
ارسال نظر