সাধারণ sensকমত্য "ব্যতিক্রম ব্যবহার করবেন না!" বেশিরভাগই অন্যান্য ভাষা থেকে আসে এবং এমনকি কখনও কখনও পুরানো হয়।
সি ++ তে, "স্ট্যাক আনওয়াইন্ডিং" এর কারণে একটি ব্যতিক্রম ছোঁড়া খুব ব্যয়বহুল । প্রতিটি স্থানীয় ভেরিয়েবল ঘোষণাটি with
পাইথনের একটি স্টেটমেন্টের মতো , এবং সেই ভেরিয়েবলের অবজেক্টটি ডেস্ট্রাক্টর চালাতে পারে। এই ডেস্ট্রাক্টরগুলি একটি ব্যতিক্রম নিক্ষেপ করা হলেও কার্যকর করা হয় তবে কোনও ফাংশন থেকে ফিরে আসার সময়। এই "আরআইআইআই আইডিয়ম" একটি অবিচ্ছেদ্য ভাষা বৈশিষ্ট্য এবং দৃ ,়, সঠিক কোড লিখতে অত্যন্ত গুরুত্বপূর্ণ - তাই আরআইআই বনাম সস্তা ব্যতিক্রম একটি ট্রেডঅফ ছিল যা সি ++ রাইয়ের প্রতি সিদ্ধান্ত নিয়েছিল।
সি ++ গোড়ার দিকে, প্রচুর কোড ব্যতিক্রম-নিরাপদ পদ্ধতিতে লেখা হয়নি: আপনি যদি সত্যই RAII ব্যবহার না করেন তবে মেমরি এবং অন্যান্য সংস্থানগুলি ফাঁস করা সহজ। সুতরাং ব্যতিক্রম ছোঁড়া সেই কোডটি ভুল উপস্থাপন করবে। এটি আর যুক্তিসঙ্গত নয় যেহেতু এমনকি সি ++ স্ট্যান্ডার্ড লাইব্রেরিও ব্যতিক্রমগুলি ব্যবহার করে: আপনি ব্যতিক্রমের অস্তিত্বের উপস্থিতি করতে পারবেন না। যাইহোক, সি কোডটি সি ++ এর সাথে সংযুক্ত করার সময় ব্যতিক্রমগুলি এখনও একটি বিষয়।
জাভাতে, প্রতিটি ব্যতিক্রমের একটি সম্পর্কিত স্ট্যাক ট্রেস রয়েছে। ত্রুটিগুলি ডিবাগ করার সময় স্ট্যাক ট্রেসটি অত্যন্ত মূল্যবান, তবে ব্যতিক্রম কখনই প্রিন্ট করা হয় না, যেমন: এটি কেবল নিয়ন্ত্রণ প্রবাহের জন্যই ব্যবহৃত হত।
সুতরাং সেই ভাষাগুলিতে ব্যতিক্রমগুলি "খুব ব্যয়বহুল" নিয়ন্ত্রণ প্রবাহ হিসাবে ব্যবহার করা যায় না। পাইথনে এটি কোনও ইস্যু কম এবং ব্যতিক্রমগুলি অনেক সস্তা। অতিরিক্তভাবে, পাইথন ভাষা ইতিমধ্যে কিছু ওভারহেডের সাথে ভুগেছে যা অন্যান্য নিয়ন্ত্রণ প্রবাহের কনস্ট্রাক্টগুলির তুলনায় ব্যতিক্রমগুলির ব্যয়কে অযৌক্তিক করে তোলে: উদাহরণস্বরূপ, কোনও স্পষ্ট সদস্যপদ পরীক্ষার সাথে ডিক এন্ট্রি উপস্থিত রয়েছে কিনা তা পরীক্ষা করে if key in the_dict: ...
নিছক প্রবেশদ্বারটি অ্যাক্সেস করার চেয়ে ঠিক তত দ্রুত the_dict[key]; ...
এবং আপনি পরীক্ষা করছেন কিনা একটি কীআরআর পান। কিছু অবিচ্ছেদ্য ভাষা বৈশিষ্ট্য (যেমন জেনারেটর) ব্যতিক্রমগুলির ক্ষেত্রে ডিজাইন করা হয়েছে।
সুতরাং পাইথনের ব্যতিক্রমগুলি এড়াতে কোনও প্রযুক্তিগত কারণ না থাকলেও, এখনও ফেরতের মানগুলির পরিবর্তে আপনার সেগুলি ব্যবহার করা উচিত কিনা তা নিয়ে এখনও প্রশ্ন রয়েছে। ব্যতিক্রমগুলি সহ ডিজাইন-স্তরের সমস্যাগুলি হ'ল:
এগুলি মোটেই সুস্পষ্ট নয়। আপনি সহজেই কোনও ফাংশনটি দেখতে পারবেন না এবং এটি দেখতে পাবে যে কোনও ব্যতিক্রমগুলি এটি ফেলে দিতে পারে, তাই আপনি কী ধরবেন তা আপনি সর্বদা জানেন না। রিটার্ন মানটি আরও সু-সংজ্ঞায়িত হতে থাকে।
ব্যতিক্রমগুলি অ-স্থানীয় নিয়ন্ত্রণ প্রবাহ যা আপনার কোডকে জটিল করে তোলে। আপনি যখন ব্যতিক্রম ছুঁড়ে মারেন, আপনি জানেন না যে নিয়ন্ত্রণ প্রবাহটি আবার শুরু হবে। ত্রুটিগুলির জন্য যা অবিলম্বে পরিচালনা করা যায় না এটি সম্ভবত একটি ভাল ধারণা, যখন আপনার কলারের শর্তটি অবহিত করার সময় এটি সম্পূর্ণ অপ্রয়োজনীয়।
পাইথন সংস্কৃতি সাধারণত ব্যাতিক্রমের পক্ষে স্ল্যাটেড তবে ওভারবোর্ডে যাওয়া সহজ। কোনও list_contains(the_list, item)
ফাংশনটি কল্পনা করুন যা তালিকায় সেই আইটেমের সমান আইটেম রয়েছে কিনা তা যাচাই করে। যদি ফলাফলটি ব্যতিক্রমগুলির মাধ্যমে জানানো হয় যা একেবারে বিরক্তিকর, কারণ আমাদের এটির মতো কল করতে হবে:
try:
list_contains(invited_guests, person_at_door)
except Found:
print("Oh, hello {}!".format(person_at_door))
except NotFound:
print("Who are you?")
একটি বিল ফিরিয়ে দেওয়া আরও পরিষ্কার হবে:
if list_contains(invited_guests, person_at_door):
print("Oh, hello {}!".format(person_at_door))
else:
print("Who are you?")
যদি ফাংশনটি ইতিমধ্যে কোনও মান ফেরত দেওয়ার কথা মনে করা হয়, তবে বিশেষ অবস্থার জন্য একটি বিশেষ মান ফিরিয়ে দেওয়া বরং ত্রুটি-ঝুঁকির কারণ, লোকেরা এই মানটি পরীক্ষা করতে ভুলে যাবে (এটি সম্ভবত সি এর মধ্যে 1/3 সমস্যার কারণ)। একটি ব্যতিক্রম সাধারণত আরও সঠিক।
একটি ভাল উদাহরণ একটি pos = find_string(haystack, needle)
ফাংশন যা needle
`খড়ের কাঠের স্ট্রিংয়ের স্ট্রিংয়ের প্রথম উপস্থিতি সন্ধান করে এবং প্রারম্ভিক অবস্থানে ফিরে আসে। তবে কী যদি তারা খড় খড়ের স্ট্রিতে সুই-স্ট্রিং না থাকে?
সি দ্বারা সমাধান এবং পাইথন দ্বারা নকল করা হল একটি বিশেষ মান ফেরত। সিতে এটি একটি নাল পয়েন্টার, পাইথনে এটি -1
। এটি পজিশন ছাড়াই স্ট্রিং সূচক হিসাবে অবস্থানটি ব্যবহার করা হলে এটি বিস্ময়কর ফলাফলের দিকে নিয়ে যায়, বিশেষত -1
পাইথনের বৈধ সূচক হিসাবে । সি-তে, আপনার ন্যূনাল পয়েন্টারটি আপনাকে কমপক্ষে একটি সেগফল্ট দেবে।
পিএইচপি-তে, ভিন্ন ধরণের একটি বিশেষ মান ফিরে আসে: FALSE
একটি পূর্ণসংখ্যার পরিবর্তে বুলিয়ান । যেহেতু এটি দেখা যাচ্ছে এটি ভাষার অন্তর্নিহিত নিয়মের কারণে আসলে এর চেয়ে ভাল কিছু নয় (তবে লক্ষ্য করুন যে পাইথনের পাশাপাশি বুলিয়ানও ইনট হিসাবে ব্যবহার করা যেতে পারে!)। ক্রমাগত ধরণের ফাংশন না দেয় এমন ফাংশনগুলি সাধারণত খুব বিভ্রান্তিকর বলে বিবেচিত হয়।
আরও শক্তিশালী বৈকল্পিকটি একটি ব্যতিক্রম ছুঁড়ে ফেলা হত যখন স্ট্রিংটি পাওয়া যায় না, যা নিশ্চিত করে যে স্বাভাবিক নিয়ন্ত্রণ প্রবাহের সময় দুর্ঘটনাক্রমে একটি সাধারণ মানের জায়গায় বিশেষ মানটি ব্যবহার করা অসম্ভব:
try:
pos = find_string(haystack, needle)
do_something_with(pos)
except NotFound:
...
বিকল্পভাবে, সর্বদা এমন টাইপ ফিরানো যা সরাসরি ব্যবহার করা যায় না তবে প্রথমে আবদ্ধ হওয়া আবশ্যক, উদাহরণস্বরূপ ফলাফল-বুল টুপল যেখানে বুলিয়ান ইঙ্গিত দেয় যে কোনও ব্যতিক্রম ঘটেছে কিনা বা ফলাফল ব্যবহারযোগ্য কিনা। তারপর:
pos, ok = find_string(haystack, needle)
if not ok:
...
do_something_with(pos)
এটি আপনাকে তাত্ক্ষণিকভাবে সমস্যাগুলি পরিচালনা করতে বাধ্য করে তবে এটি খুব দ্রুত বিরক্তিকর হয়ে ওঠে। এটি আপনাকে সহজে চেইন ফাংশন থেকে বাধা দেয়। প্রতিটি ফাংশন কল এখন কোড তিন লাইন প্রয়োজন। গোলং এমন একটি ভাষা যা মনে করে যে এই উপদ্রবটি সুরক্ষার পক্ষে মূল্যবান।
সুতরাং সংক্ষেপে বলতে গেলে ব্যতিক্রমগুলি পুরোপুরি সমস্যা ছাড়াই নয় এবং যথাযথভাবে অতিরিক্ত ব্যবহার করা যায়, বিশেষত যখন তারা একটি "স্বাভাবিক" রিটার্ন মান প্রতিস্থাপন করে। তবে যখন বিশেষ শর্তগুলির সংকেত দেওয়ার জন্য ব্যবহৃত হয় (অগত্যা কেবল ত্রুটি নয়) তবে ব্যতিক্রমগুলি আপনাকে এমন এপিআই বিকাশ করতে সহায়তা করবে যা পরিষ্কার, স্বজ্ঞাত, ব্যবহারযোগ্য সহজ এবং অপব্যবহার করা কঠিন।