مدیریت استثنا در پایتون
در برنامهنویسی بسیار رایج است که به خطا (error) برخورد کنید. دو نوع خطاهایی که ممکن است پیش بیاید، خطای نحوی و استثنا میباشد. خطای نحوی به خطایی گفته میشود که در خلال نوشتن کد رخ میدهد که دستوری را به اشتباه نوشته باشید. در این حالت تجزیه کننده (parser) آن زبان، خطی که اشتباه نوشته شده را به شما نشان میدهد.
استثناها نوع دیگری از خطاهاست:
استثناها مشکلاتی هستند که در هنگام اجرای برنامهها ممکن است رخ دهند و در اجرایِ برنامه اختلال ایجاد کنند.
برای مثال فرض کنید که در برنامه خود بخواهید که از کاربر عددی را دریافت کنید تا عمل تقسیم را روی آن انجام دهید. حال اگر کاربر به جای عدد، رشته وارد کند، تقسیم رشته بر عدد بیمعنی میشود. این نوع خطا را استثنا گویند.
برخی از استثناها
در این جا به معرفی برخی از استثناها که ممکن است بیشتر با آنها مواجه شوید، میپردازیم:
- NameError : این استثنا زمانی رخ میدهد که برنامه نتواند اسمی را پیدا کند.
print(x) """ Traceback (most recent call last): File "ZeroToHero.py", line 1, in <module> print(x) NameError: name 'x' is not defined """
- TypeError : این استثنا زمانی رخ میدهد که نوع اشتباهی به عنوان آرگومان داده شود.
var = input("Enter your number: ") print(var+2) """ Traceback (most recent call last): File "ZeroToHero.py", line 2, in <module> print(var+2) TypeError: Can't convert 'int' object to str implicitly """
- ValueError : این استثنا زمانی رخ میدهد که نوع درست و مقدار اشتباه باشد.
var = int(input("Enter your number: ")) # Suppose we enter "ZeroToHero" as an input print(var) """ Traceback (most recent call last): File "ZeroToHero.py", line 1, in <module> var = int(input("Enter your number: ")) ValueError: invalid literal for int() with base 10: 'ZeroToHero' """
NotImplementedError : این استثنا زمانی رخ میدهد که کلاسِ انتزاعی داشته باشیم که کدی در آن نوشته نشده باشد.
class FatherClass(object): def _print(self): raise NotImplementedError class ChildClass(FatherClass): def _print(self): print("ZeroToHero") c1 = FatherClass() c1._print() """ Traceback (most recent call last): File "ZeroToHero.py", line 10, in <module> c1._print() File "ZeroToHero.py", line 3, in _print raise NotImplementedError NotImplementedError """
- ZeroDivisionError : این استثنا زمانی رخ میدهد که بخواهیم عددی را بر صفر تقسیم کنیم. (زیر مجموعه ArithmeticError میباشد.)
print(2/0) """ Traceback (most recent call last): File "ZeroToHero.py", line 1, in <module> print(2/0) ZeroDivisionError: division by zero """
- FileNotFoundError : این استثنا زمانی رخ میدهد که فایل یا مسیر درخواستی وجود نداشته باشد.
file = open("ZeroToHero1.txt") """ Traceback (most recent call last): File "ZeroToHero.py", line 1, in <module> file = open("ZeroToHero1.txt") FileNotFoundError: [Errno 2] No such file or directory: 'ZeroToHero1.txt' """
برای دیدن تمامی استثناها در پایتون به این لینک مراجعه کنید.
مدیریت استثنا
طبیعی است استثناهایی که در برنامه ممکن است رخ دهد، باید مدیریت شوند تا در کارکرد بقیه اجزای برنامه مشکل بوجود نیاورد.
قدم اول این است کدی که حدس میزنیم به مشکل برخورد کند را در try بگذاریم. قدم بعدی استفاده از except برای مدیریت کردنِ استثنا، در صورتی که کدی که در try قرار دارد به مشکل برخورد کند، است.
به مثال زیر برای مدیریت کردن ValueError دقت کنید:
while 1: try: x = int(input("Please enter a number: ")) print("Dividing ",x, "by 10 will give you :", x/10) except ValueError: print("The input was not an integer. Please try again...")
زمانی که کد درونِ try اجرا میشود، اگر به مشکلی برخورد نکند except را نادیده میگیرد و برنامه به کار خود ادامه میدهد. اما اگر به مشکل برخورد کند، برنامه ادامه کد را اجرا نمیکند و به except میرود. اگر نامِ استثنا با استثنایی که رخ داد یکسان بود کد درونِ except اجرا میشود، در غیر این صورت برنامه با error متوقف میشود.
در مثال بالا اگر کاربر هر ورودی غیر از عدد صحیح (integer) وارد کند، برنامه دچار مشکل شده و عبارت داخل except را به کاربر نشان میدهد.
همچنین میتوانید چندین except در برنامه خود داشته باشید و حتی چندین استثنا را در یک except مدیریت کنید.
while 1: try: x = int(input("Please enter a number: ")) print("Dividing 50 by", x,"will give you :", 50/x) except (ValueError, ZeroDivisionError): print("The input was not valid. Please try again...")
در این مثال ممکن است کاربر ورودی غیر عددِ صحیح بدهد و هم ممکن است ۰ را وارد کند.
استفاده از Else
else زمانی استفاده میشود که نیاز دارید استثنای کدی گرفته نشود یا احتمال میدهید که استثنایی بوجود نمیآورد. else را بعد از except تعریف میکنند که اگر try بدون مشکل اجرا شد، except نادیده گرفته شود و کدهای درونِ else اجرا شود.
while 1: try: x = int(input("Please enter a number: ")) except ValueError: print("The input was not an integer. Please try again...") else: print("Dividing ",x, "by 10 will give you :", x/10)
در این مثال میدانیم که دستور print استثنایی بوجود نمیآورد، پس آن را در else میگذاریم.
استفاده از Finally
فرض کنید کدی در try نوشتید که قرار است مقدار زیادی از منابع سخت افزاری را به کار بگیرد. ضروری است که بعد از اتمام استفاده از آنها منابع را آزاد کنید. این کار را به راحتی میتوانید در finally انجام دهید. تمام کدهایی که در finally قرار میگیرد همیشه اجرا میشود.
while 1: try: x = int(input("Please enter a number: ")) except ValueError: print("The input was not an integer. Please try again...") else: print("Dividing ",x, "by 10 will give you :", x/10) finally: print("Usage of Finally (ZeroToHero)")
مثالی پیچیدهتر از مدیریت استثنا
در این قسمت برنامه ای خواهیم نوشت که لگاریتم مقادیرِ یک لیست را حساب میکند.
import math number_list = [10,-5,1.2,'apple'] try: for number in number_list: try: number_factorial = math.log10(number) except TypeError: print("Factorial is not supported for given input type.") except ValueError: print("Factorial only accepts positive integer values.", number," is not a positive integer.") else: print("The factorial of",number,"is", number_factorial) except: print("Something happened") finally: print("Releasing resources...") del number_list
زمانی که کد بالا اجرا شود، خروجی زیر حاصل میشود:
The factorial of 10 is 1.0 Factorial only accepts positive integer values. -5 is not a positive integer. The factorial of 1.2 is 0.07918124604762482 Factorial is not supported for given input type. Releasing resources...
سعی کنید تا جای ممکن در برنامههای خود استثناها را مدیریت کنید تا از خطاهای ناخواسته جلوگیری کنید. این عمل همچنین در فرآیندِ debugging کمک بسیاری به شما خواهد کرد.
دیدگاهتان را بنویسید
برای نوشتن دیدگاه باید وارد بشوید.