আকর্ষণীয়: আপনি সঠিকভাবে অনুমিত হিসাবে, সেখানে এটি দুটি পক্ষই কোন পর এর ব্যতিক্রম টাইপ নির্দিষ্ট করে ত্রুটি except
এবং নিছক কোন পদক্ষেপ গ্রহণ ছাড়াই এটি ক্ষণস্থায়ী।
আমার ব্যাখ্যাটি "কিছুটা" দীর্ঘ — তাই tl; ডাঃ এটির সাথে এটি ভেঙে যায়:
- কোনও ত্রুটি ধরবেন না । আপনি যে ব্যতিক্রমগুলি থেকে পুনরুদ্ধার করতে প্রস্তুত এবং কেবল সেগুলি ধরতে প্রস্তুত তা সর্বদা নির্দিষ্ট করুন।
- ব্লক ব্যতীত পাস এড়ানো চেষ্টা করুন । সুস্পষ্টভাবে কাঙ্ক্ষিত না হলে এটি সাধারণত কোনও ভাল লক্ষণ নয়।
তবে আসুন বিশদে যাওয়া যাক:
কোনও ত্রুটি ধরবেন না
কোনও try
ব্লক ব্যবহার করার সময় , আপনি সাধারণত এটি করেন কারণ আপনি জানেন যে ব্যতিক্রম ছোঁড়ার সম্ভাবনা রয়েছে। এই হিসাবে, আপনার ইতিমধ্যে কী ভাঙতে পারে এবং কোন ব্যতিক্রম নিক্ষেপ করা যেতে পারে তার একটি আনুমানিক ধারণা রয়েছে । এই ধরনের ক্ষেত্রে, আপনি একটি ব্যতিক্রম ধরা কারণ আপনি ইতিবাচকভাবে এটি থেকে পুনরুদ্ধার করতে পারেন । তার মানে আপনি ব্যতিক্রমের জন্য প্রস্তুত এবং কিছু বিকল্প পরিকল্পনা রয়েছে যা আপনি সেই ব্যতিক্রমের ক্ষেত্রে অনুসরণ করবেন।
উদাহরণস্বরূপ, আপনি যখন কোনও সংখ্যাকে ইনপুট করার জন্য ব্যবহারকারীকে জিজ্ঞাসা করেন, আপনি ইনপুটটি রূপান্তর করতে পারেন int()
যা ব্যবহার করে একটি উত্থাপিত হতে পারে ValueError
। আপনি সহজেই ব্যবহারকারীকে আবার চেষ্টা করার জন্য বলার মাধ্যমে সহজেই এটি পুনরুদ্ধার করতে পারেন, সুতরাং ValueError
ব্যবহারকারীকে ধরা এবং আবার অনুরোধ করা একটি উপযুক্ত পরিকল্পনা হবে। অন্য কোনও উদাহরণ হতে পারে যদি আপনি কোনও ফাইল থেকে কিছু কনফিগারেশন পড়তে চান এবং সেই ফাইলটির অস্তিত্ব ঘটে না। এটি একটি কনফিগারেশন ফাইল হওয়ায় আপনার ফ্যালব্যাক হিসাবে কিছু ডিফল্ট কনফিগারেশন থাকতে পারে, সুতরাং ফাইলটি ঠিক প্রয়োজনীয় নয়। সুতরাং একটি ধরা FileNotFoundError
এবং কেবল ডিফল্ট কনফিগারেশন প্রয়োগ করা এখানে একটি ভাল পরিকল্পনা হবে। এখন এই উভয় ক্ষেত্রেই আমাদের একটি খুব নির্দিষ্ট ব্যতিক্রম রয়েছে যা আমরা প্রত্যাশা করি এবং এটি থেকে পুনরুদ্ধারের জন্য সমানভাবে নির্দিষ্ট পরিকল্পনা রয়েছে। যেমন, প্রতিটি ক্ষেত্রে, আমরা স্পষ্টভাবে কেবল except
এটি নির্দিষ্ট ব্যতিক্রম।
তবে, যদি আমরা সমস্ত কিছু ধরতে পারি তবে — ব্যতিক্রমগুলি থেকে আমরা পুনরুদ্ধার করতে প্রস্তুত addition এছাড়াও এমন একটি সম্ভাবনাও রয়েছে যা আমরা প্রত্যাশা করি নি এবং আমরা প্রকৃতপক্ষে পুনরুদ্ধার করতে পারি না; বা পুনরুদ্ধার করা উচিত নয়।
উপরের থেকে কনফিগারেশন ফাইলের উদাহরণটি নেওয়া যাক। অনুপস্থিত ফাইলের ক্ষেত্রে, আমরা সবেমাত্র আমাদের ডিফল্ট কনফিগারেশন প্রয়োগ করেছি এবং পরবর্তী সময়ে স্বয়ংক্রিয়ভাবে কনফিগারেশনটি সংরক্ষণ করার সিদ্ধান্ত নিয়েছি (সুতরাং পরবর্তী সময় ফাইলটি উপস্থিত থাকবে)। এখন কল্পনা করুন আমরা একটি IsADirectoryError
, বা একটি পেয়েছিPermissionError
পরিবর্তে. এই ধরনের ক্ষেত্রে, আমরা সম্ভবত চালিয়ে যেতে চাই না; আমরা এখনও আমাদের ডিফল্ট কনফিগারেশন প্রয়োগ করতে পারি, তবে আমরা পরে ফাইলটি সংরক্ষণ করতে পারব না। এবং সম্ভবত এটি ব্যবহারকারীর একটি কাস্টম কনফিগারেশনও বোঝানো হয়েছে, তাই ডিফল্ট মানগুলি ব্যবহার করা সম্ভবত পছন্দসই নয়। সুতরাং আমরা অবিলম্বে এটি সম্পর্কে ব্যবহারকারীকে বলতে চাই এবং সম্ভবত প্রোগ্রামের প্রয়োগও বাতিল করে দিতে পারি। তবে এটি এমন কিছু নয় যা আমরা কিছু ছোট কোডের অভ্যন্তরে গভীরভাবে করতে চাই; এটি অ্যাপ্লিকেশন-স্তরের গুরুত্বের কিছু, তাই এটি শীর্ষে পরিচালনা করা উচিত - সুতরাং ব্যতিক্রমটি বুদবুদ হয়ে উঠুক।
পাইথন 2 আইডিয়াম নথিতে আরও একটি সহজ উদাহরণ উল্লেখ করা হয়েছে । এখানে কোডে একটি সাধারণ টাইপ রয়েছে যা এটি ভেঙে দেয়। যেহেতু আমরা প্রতিটি ব্যতিক্রম ধরছি , আমরা NameError
এস এবং SyntaxError
এসও ধরছি । উভয়ই ভুলত্রুটি যা প্রোগ্রামিংয়ের সময় আমাদের সকলের হয়; এবং উভয়ই ভুল যা আমরা কোড শিপিংয়ের সময় একেবারে অন্তর্ভুক্ত করতে চাই না। তবে আমরা সেগুলিও ধরা পড়েছি, আমরা এমনকি তাদের জানব না যে সেগুলি সেখানে ঘটেছে এবং সঠিকভাবে এটি ডিবাগ করার জন্য কোনও সহায়তা হারাবে না।
তবে আরও বিপজ্জনক ব্যতিক্রমগুলিও রয়েছে যার জন্য আমরা সম্ভবত প্রস্তুত নই। উদাহরণস্বরূপ, সিস্টেমেররার হ'ল এমন একটি জিনিস যা খুব কমই ঘটে থাকে এবং যার জন্য আমরা সত্যিই পরিকল্পনা করতে পারি না; এর অর্থ এখানে আরও জটিল কিছু চলছে, যা সম্ভবত আমাদের বর্তমান কাজটি চালিয়ে যাওয়া থেকে বাধা দেয়।
যাইহোক, কোডের একটি ছোট স্কেল অংশে আপনি সমস্ত কিছুর জন্য প্রস্তুত, এটি খুব কমই সম্ভাবনা, তাই এটিই সত্য যেখানে আপনার কেবল প্রস্তুত হওয়া ব্যতিক্রমগুলিই ধরা উচিত for কিছু মানুষ অন্তত ধরা সুপারিশ Exception
যেমন ভীষণ পছন্দ অন্তর্ভুক্ত করবে না SystemExit
এবং KeyboardInterrupt
যা নকশা আপনার আবেদন বিনষ্ট, কিন্তু আমি তর্ক করবে এই এখনও পর্যন্ত খুব অনুল্লেখিত হয়। কেবলমাত্র একটি জায়গা যেখানে আমি ব্যক্তিগতভাবে ধরা Exception
বা কেবল যে কোনও গ্রহণ করিব্যতিক্রম, এবং এটি একক বিশ্বব্যাপী অ্যাপ্লিকেশন-স্তরের ব্যতিক্রম হ্যান্ডলারে রয়েছে যার কোনও বিকল্প ব্যতিক্রম লগ করার একক উদ্দেশ্য আমাদের জন্য প্রস্তুত ছিল না। এইভাবে, আমরা এখনও অপ্রত্যাশিত ব্যতিক্রমগুলি সম্পর্কে যথাযথ তথ্য ধরে রাখতে পারি, যা পরে আমরা সেগুলি স্পষ্টভাবে পরিচালনা করার জন্য আমাদের কোডটি প্রসারিত করতে (যদি আমরা সেগুলি থেকে পুনরুদ্ধার করতে পারি) বা — কোনও বাগের ক্ষেত্রে — পরীক্ষার কেসগুলি তৈরি করতে নিশ্চিত করতে পারি এটি আর ঘটবে না। তবে অবশ্যই এটি কেবলমাত্র তখনই কার্যকর হয় যদি আমরা ইতিমধ্যে ইতিমধ্যে প্রত্যাশিত ব্যতিক্রমগুলি ধরে ফেলতাম, যার ফলে আমরা প্রত্যাশা করি না তারা স্বাভাবিকভাবেই বুদবুদ হয়ে যাবে।
ব্লক ব্যতীত পাস এড়ানো চেষ্টা করুন
স্পষ্টভাবে নির্দিষ্ট ব্যতিক্রমগুলির একটি ছোট নির্বাচনকে ধরার সময়, অনেকগুলি পরিস্থিতি রয়েছে যেখানে আমরা কিছু না করে ঠিক হয়ে যাব। এই ধরনের ক্ষেত্রে, ঠিক থাকা except SomeSpecificException: pass
ঠিক আছে। যদিও বেশিরভাগ সময় এটি হয় না কারণ আমাদের সম্ভবত পুনরুদ্ধার প্রক্রিয়া সম্পর্কিত কিছু কোডের প্রয়োজন (উপরে বর্ণিত হিসাবে)। এটি উদাহরণস্বরূপ এমন কিছু হতে পারে যা আবার ক্রিয়াটি আবার চেষ্টা করে বা এর পরিবর্তে একটি ডিফল্ট মান সেট করে।
যদি তা না হয় তবে উদাহরণস্বরূপ, কারণ আমাদের কোডটি এটি সাফল্য না হওয়া পর্যন্ত পুনরাবৃত্তি করার জন্য ইতিমধ্যে কাঠামোগত তৈরি করা হয়েছে, তবে কেবল পাশ করা যথেষ্ট passing উপরে থেকে আমাদের উদাহরণ গ্রহণ করে, আমরা ব্যবহারকারীকে একটি নম্বর লিখতে বলি। যেহেতু আমরা জানি যে ব্যবহারকারীরা তাদের কাছে যা চান আমরা তা করতে চাই না, আমরা কেবল এটি প্রথমে একটি লুপে রেখে দিতে পারি, যাতে এটি দেখতে দেখতে:
def askForNumber ():
while True:
try:
return int(input('Please enter a number: '))
except ValueError:
pass
যেহেতু আমরা চেষ্টা চালিয়ে যাচ্ছি যতক্ষণ না কোনও ব্যতিক্রম ছোঁড়া হয়, তাই ব্লক ব্যতীত আমাদের বিশেষ কিছু করার দরকার নেই, সুতরাং এটি ঠিক আছে। তবে অবশ্যই একটি যুক্তি হতে পারে যে আমরা অন্তত ব্যবহারকারীকে কিছুটা ত্রুটি বার্তা দেখাতে চাই কারণ তাকে কেন ইনপুটটি পুনরাবৃত্তি করতে হবে tell
যদিও অন্য অনেক ক্ষেত্রে, কেবল একটি পাস except
করা একটি লক্ষণ যে আমরা যে ব্যতিক্রমটি ধরছি তার জন্য আমরা সত্যিই প্রস্তুত ছিলাম না। যদি না এই ব্যতিক্রমগুলি সহজ (যেমন ValueError
বা TypeError
) হয় না এবং কারণটি আমরা পাশ করতে পারি তা স্পষ্ট না হয়, কেবল পাসিং এড়াতে চেষ্টা করুন। যদি সত্যিই কিছু করার থাকে না (এবং আপনি এটি সম্পর্কে একেবারে নিশ্চিত), তবে সে ক্ষেত্রে কেন একটি মন্তব্য যুক্ত করার বিষয়টি বিবেচনা করুন; অন্যথায়, আসলে কিছু পুনরুদ্ধার কোড অন্তর্ভুক্ত ব্যতীত ব্লকটি প্রসারিত করুন।
except: pass
সবচেয়ে খারাপ অপরাধী যদিও উভয়ের সংমিশ্রণ। এর অর্থ হ'ল আমরা স্বেচ্ছায় কোনও ত্রুটি ধরছি যদিও আমরা এর জন্য একেবারেই প্রস্তুত নই এবং আমরা এটি সম্পর্কে কিছু করি না। আপনি কমপক্ষে ত্রুটিটি লগ করতে চান এবং অ্যাপ্লিকেশনটি শেষ করতে সম্ভবত পুনরায় এটি প্রয়োগ করতে চান (মেমোরিঅরারের পরে আপনি স্বাভাবিকের মতো চালিয়ে যেতে পারবেন না)। কেবল পাস করলেই অ্যাপ্লিকেশনটি কিছুটা জীবিত থাকবে না (নির্ভর করে আপনি অবশ্যই ধরেন) তবে ত্রুটিটি আবিষ্কার করা অসম্ভব করে তোলে - যা আপনি যদি আবিষ্কার করেন না তবে বিশেষত সত্য।
সুতরাং নীচের লাইনটি হল: কেবলমাত্র ব্যতিক্রমগুলি ধরুন যা আপনি সত্যই প্রত্যাশা করেন এবং পুনরুদ্ধার করতে প্রস্তুত; অন্য সমস্তগুলি সম্ভবত হয় আপনার ভুলগুলি সংশোধন করা উচিত, বা এমন কোনও কিছু যা আপনি এখনও প্রস্তুত নন। আপনার যদি সত্যিই সেগুলি সম্পর্কে কিছু করার প্রয়োজন না হয় তবে নির্দিষ্ট ব্যতিক্রমগুলি উত্তীর্ণ । অন্যান্য সমস্ত ক্ষেত্রে, এটি অনুমান এবং অলস হওয়ার কেবল চিহ্ন। এবং আপনি অবশ্যই এটি ঠিক করতে চান।
logging
তাদের উত্পাদনে প্রবাহিত স্ট্রিমিং এড়াতে DEBUG পর্যায়ে মডিউলটি ব্যবহার করুন , তবে তাদের বিকাশে উপলব্ধ রাখুন।