Exception Handling in Python

কোড করতে গিয়ে অসঙ্গত অপারেশন অথবা ভুল ইনপুট ইত্যাদি নানা কারণে এক্সসেপশন / এরর আসতেই পারে। পাইথন নিজে থেকে এগুলো সল্ভ করে দিবে না। কোন একটা লাইনের এক্সেপশন আমাদের পুরো প্রোগ্রাম কে বন্ধ করে দিতে পারে। সেক্ষেত্রে, সবচেয়ে ভালো উপায় হচ্ছে সতর্কতার সাথে , সেই সব এরর / এক্সেপশন হ্যান্ডেল করার কোড লিখে রাখা। তবে , শুধু মাত্র যেসব জায়গায় এরর / এক্সেপশন আসতে পারে সেইসব জায়গায়। তাহলে , আমাদের পুরো প্রোগ্রাম বন্ধ ও হবে না এবং আমরা আমাদের ভুলগুলো ও সাথে সাথে টার্মিনাল থেকে দেখে নিতে পারবো।

 

 
==<i>**Syntax**</i>==
try:
# statement_1
# statement_2


# statement_n


except:
# execute if error occured in try block

 

 

 

যেই কোড গুলো ভুল হবার সম্ভাবনা রয়েছে সেগুলো আমরা `try` block এ লিখবো। ভুল হলে , প্রোগ্রামটি বন্ধ হবার পরিবর্তে পাইথনকে কি করতে হবে , সেই সমস্ত ইন্সট্রাকশন `except` এ লিখে দিবো। `try` block এ যদি কোনো এক্সেপশন / এরর না থাকে , তাহলে কখনোই `except` block কাজ করবে না। `try` block এ একটি ভুল হলেই `except` block কাজ করবে ।

 

python
 
try:
    print( 2 + 2 )
    x = 4
    print( x / 10 )
    print("Last Line")
except:
    print("Error Occured")


// **output**


// 4
// 0.4
// Last Line

 

 
উপরের উদাহরণে `try` block এ কোনো এক্সেপশন / এরর নেই , এজন্য `except` block এর লিখা প্রিন্ট হয় নি।
এখন যদি আমরা একটি ভুল করি —
python
try:
    print( 2 + 2 )
    x = 4
    print( x / 0 )
    print("Last Line")
except:
    print("Error Occured")


// **output**


// 4
// Error Occured

 

 

 
তাহলে দেখা যাচ্ছে 3 no. লাইন পর্যন্ত `try` block এ কোন সমস্যা ছিল না বলেই , `try` block এর 3 no. লাইন পর্যন্ত এক্সিকিউট হয়েছে। যখন 4 no. লাইনে আমরা ০ দিয়ে ভাগ দিতে চেয়েছি যেটা আসলে একটা এরর , এরজন্য এরপর থেকে আর কোন লাইন `try` block এ এক্সিকিউট না হয়ে , সরাসরি `except` এ চলে গিয়ে “`Error Occured`” (যেটা আমরা এ লিখেছি ) প্রিন্ট করেছে।

 

তবে , একটি সমস্যা আছে , আমরা টার্মিনাল দেখে বলতে পারবো না , আসলে কি ভুল হয়েছে , এজন্য এরর মেসেজটি স্পেসিফিকভাবে লিখা ভালো।
python
try:
    print( 2 + 2 )
    x = 4
    print( x / 0 )
    print("Last Line")
except:
    print("Error ! Can not divided by zero")


// **output**


// 4
// Error ! Can not divided by zero

 

 
বেশ ! কিন্তু , সবসময় এরর / এক্সসেপশন আমাদের জানার মধ্যে নাও থাকতে পারে। যেকোনো এক্সেপশন হলে কি করতে হবে , সেই মেসেজ এর দায়ভার আমরা পাইথনের উপর ছেড়ে দিতে পারি।

 

python=
try:
    print( 2 + 2 )
    x = 4
    print( x / 0 )
    print("Last Line")
except Exception as e:
    print(f"Error ! {e}")

 

 
`Exception` keyword দিয়ে এক্সেপশন ধরে এর `e` variable এর মধ্যে স্টোর করলাম। যার ফলে , যেকোনো এক্সেপশন হোক না কেন , আমরা সেই দায়িত্ব পাইথনের হাতে ছেড়ে দিলাম। এবং পাইথন ই এরর মেসেজ জেনারেট করে দিবে।
আরেকটি বিষয় থেকে যায় সেটা হলো , ঢালাওভাবে সব এক্সেপশন হ্যান্ডেল করাটা ভালো অভ্যাস না। স্পেসিফিক এক্সসেপশন-ই আমাদের হ্যান্ডেল করা উচিত।
python
try:
    print( 2 + 2 )
    x = 4
    print( x / 0 )
    print("Last Line")
except ZeroDivisionError as e:
    print(f"Error : {e}")

 

 
সো , এভাবে এক্সেপশন গুলো ধরলে , কোডের রিডিবিলিটি ভালো থাকে।

 

আমরা চাইলে একটি `try` block এর জন্য মাল্টিপল `except` block রাখতে পারি। এখানে একটি বিষয় লক্ষ্যণীয় , অনেকগুলা `except` block থাকলেও মাত্র একটা `except` block কাজ করবে , এবং এর মধ্যে যেই এক্সেপশন আগে ঘটবে , তার জন্য লেখা `except` block কাজ করবে।
python
try:
    print( 2 + 2 )
    x = 4
    print( y / 0 )
    print("Last Line")
except ZeroDivisionError as e:
    print(f"Error : {e}")
except NameError as e:
    print(f"Error : {e}")  

 

 
দেখেই বুঝতে পেরেছেন , 4 no. লাইনে ভুল করেছি। কিন্তু এখানে ভুল করেছি দুইটা। ১) `y` variable টি আগে কোথাও ডিফাইন করা ছাড়াই এখানে ব্যবহার করছি , ২)`y` কে ০ দ্বারা ভাগ করছি।
আবার লিখার জন্য লিখেছি আগে এবং লিখেছি পরে। কিন্তু পাইথন কোড এক্সিকিউট করার সময় আগে `y` কে পাবে , তাই `NameError` এক্সসেপশন ব্লকটাই কাজ করবে ।
 //**output**


// 4
// Error : name 'y' is not defined

 

 
এই `try-except` ব্লক এর সাথে আরেকটা block পাইথন আমাদেরকে অতিরিক্ত দিয়ে থাকে। সেটা হচ্ছে ==`finally`== block। এই block এর কাজ হচ্ছে , যে `try` / `except` যেটাই কাজ করুক না কেন , তার পরে সবার শেষে `finally` block কাজ করবেই।
 

 

python
try:
    print( 2 + 2 )
    x = 4
    print( y / 0 )
except ZeroDivisionError as e:
    print(f"Error : {e}")
except NameError as e:
    print(f"Error : {e}")
finally:
    print("I am 'finally' working...")






// **output**
// 4
// Error : name 'y' is not defined
// I am 'finally' working...

 

 
ধরেন ,`try` block এ কোন ধরণের এরর / এক্সেপশন হয় নি , এবং এটার জন্য , আমরা `try` block এর কোন ডাটা এর উপর কোন কাজ করতে চাচ্ছি। সেটা করতে গেলে , পাইথন আমাদের কে আরো একটা block দিয়ে থাকে। সেটা হচ্ছে `else` block। এটা কিন্তু `if-else` এর `else` না।
python=
try:
    print( 2 + 2 )
    x = 4
    y = x / 2
except ZeroDivisionError as e:
    print(f"Error : {e}")
except NameError as e:
    print(f"Error : {e}")
else:
# working if try block is completely error free
    print(f"Value of y is {y}")
finally:
    print("I am 'finally' working...")


// **output**


// 4
// Value of y is 2.0
// I am 'finally' working...

 

 
_`else` block কাজ করতে হলে , `try` block এ কোন ধরণের এক্সেপশন থাকা যাবে না_
উদাহরন
some = "1_vivasoft"




try:
print(some[15])
except IndexError as e:
try:
print(f"Integer : {int(some[0])}")
exceptValueErrorase:
print(some[0])


// output
// ---------------------------
// Integer : 1


 

এসো নিজে করি
অনুশীলনী
 
* এমন একটি টেক্সট ফাইল ওপেন করার চেষ্টা করুন , যেটি আপনার ডিস্কে নেই , এবং যথাযথ এরর প্রিন্ট করে দেখান ।
* একটি ফাংশন দুইটি প্যারামিটার নেয় , এবং এর কাজ হচ্ছে ভাগফল বের করে দেয়া। ফাংশনটি এমনভাবে লিখুন যেন কখনই এরর না দেয়। (sample input: a=10,b=5 | a=”a”,b=10 | a= 10 , b= 0)
ইন্টারভিউ প্রশ্নোত্তর
গুরুত্বপূর্ন প্রশ্নসমুহ
1. কোন keyword দিয়ে আমরা এরর গুলো দেখতে পারি ?
2. কোন ব্লক দিয়ে আমরা ঝামেলাপুর্ন কোড হ্যান্ডেল করি ?
3. এরর হ্যান্ডেল করা কেন জরুরী ?