python tutorial কিছু করার চেষ্টা করা ভাল এবং আপ ব্যতিক্রম বা পরীক্ষার ধরা যদি এটি প্রথম ব্যতিক্রম ব্যতিক্রম এড়ানো সম্ভব?




python tutorial (7)

নীরবভাবে ক্ষণস্থায়ী ত্রুটি হিসাবে ব্যাখ্যা করা হবে যদি পরিবর্তে একটি চেষ্টা ব্যবহার করা উচিত? এবং যদি তাই হয়, আপনি স্পষ্টভাবে এই ভাবে এটি ব্যবহার করে silencing হয়, তাই এটা ঠিক আছে?

try ব্যবহার try স্বীকার করা হয় যে একটি ত্রুটি পাস হতে পারে, এটি নীরবভাবে পাস করার বিপরীত। except এটি ব্যবহার করা হয় না এ সব পাস।

try: except: ব্যবহার try: except: ক্ষেত্রে যেখানে পছন্দ করা হয় if: else: যুক্তি আরো জটিল। সহজ জটিল চেয়ে ভাল; জটিল জটিল চেয়ে ভাল; এবং অনুমতি চেয়ে ক্ষমা চাইতে চাইতে সহজ।

"ত্রুটিগুলি কখনই নীরবভাবে পাস করা উচিত নয়" এটি সম্পর্কে সতর্কতা অবলম্বন করে, কোডটি এমন একটি ব্যতিক্রম যা বাড়াতে পারে যেখানে আপনি জানেন এবং যেখানে আপনার নকশাটি স্বীকার করে তবে আপনি ব্যতিক্রমটির সাথে মোকাবিলা করার জন্য ডিজাইন করেননি। স্পষ্টতই একটি ত্রুটি নীরব করা, আমার দৃষ্টিতে, ব্লক except এমন কিছু করা যাচ্ছিল, যা কেবলমাত্র "কিছুই না করা" বোঝার সাথেই করা উচিত, বিশেষ অবস্থানে সঠিক ত্রুটি পরিচালনা করা। (এটি সম্ভবত কয়েকটি বার যেখানে আমি ভাল লেখনী কোডে একটি মন্তব্য চাই মনে হয় সম্ভবত প্রয়োজন।)

যাইহোক, আপনার বিশেষ উদাহরণে, না উপযুক্ত:

x = myDict.get('ABC', 'NO_ABC')

কারণ প্রত্যেকেই এই দিকে ইঙ্গিত দিচ্ছে - যদিও আপনি সাধারণভাবে বুঝতে আপনার ইচ্ছা এবং একটি ভাল উদাহরণ নিয়ে আসতে ব্যর্থতা স্বীকার করেন - তবে সমান পার্শ্ব-পদক্ষেপ প্রকৃতপক্ষে বেশিরভাগ ক্ষেত্রেই বিদ্যমান থাকে এবং তাদের সন্ধান করা হয় সমস্যা সমাধানের প্রথম পদক্ষেপ।

কিছু পরীক্ষা করা উচিত if তা যাচাই করা উচিত নাকি এটি করার try করা উচিত এবং ব্যতিক্রমটি ধরতে হবে?

  • এক উপায় পছন্দ করা হয় যে কোন কঠিন ডকুমেন্টেশন আছে?
  • একটি উপায় আরো Pythonic হয় ?

উদাহরণস্বরূপ, আমি কি করা উচিত:

if len(my_list) >= 4:
    x = my_list[3]
else:
    x = 'NO_ABC'

বা:

try:
    x = my_list[3]
except IndexError:
    x = 'NO_ABC'

কিছু চিন্তা ...
PEP 20 বলেছেন:

ত্রুটি নীরবভাবে পাস করা উচিত নয়।
স্পষ্টভাবে নিরব না।

নীরবভাবে ক্ষণস্থায়ী ত্রুটি হিসাবে ব্যাখ্যা করা হবে if পরিবর্তে একটি try ব্যবহার করা উচিত? এবং যদি তাই হয়, আপনি স্পষ্টভাবে এই ভাবে এটি ব্যবহার করে silencing হয়, তাই এটা ঠিক আছে?

আমি পরিস্থিতিতে উল্লেখ করছি না যেখানে আপনি শুধুমাত্র জিনিস 1 উপায় করতে পারেন; উদাহরণ স্বরূপ:

try:
    import foo
except ImportError:
    import baz

যখনই আপনি নিয়ন্ত্রণ প্রবাহ try/except ব্যবহার try/except , নিজেকে জিজ্ঞাসা করুন:

  1. এটি কি সহজে দেখার try যখন try ব্লক সফল হয় এবং এটি ব্যর্থ হয়?
  2. আপনি ব্লক try ভিতরে সব পার্শ্ব প্রতিক্রিয়া সচেতন?
  3. আপনি কি সব ক্ষেত্রে অবগত আছেন যাতে try ব্লক ব্যতিক্রমটি ছুঁড়ে ফেলে?
  4. try ব্লক বাস্তবায়ন যদি, আপনার নিয়ন্ত্রণ প্রবাহ এখনও প্রত্যাশিত হিসাবে আচরণ করবে?

যদি এই এক বা একাধিক প্রশ্নের উত্তর 'না' হয়, তাহলে জিজ্ঞাসা করতে অনেক ক্ষমা হতে পারে; সম্ভবত আপনার ভবিষ্যত স্ব থেকে সম্ভবত।

একটি উদাহরণ. আমি সম্প্রতি এমন একটি বড় প্রকল্পে কোড দেখেছি যা এই রকম লাগছিল:

try:
    y = foo(x)
except ProgrammingError:
    y = bar(x)

প্রোগ্রামারের সাথে কথা বলা হয়েছে যে অভিযোজিত নিয়ন্ত্রণ প্রবাহটি ছিল:

যদি x একটি পূর্ণসংখ্যা হয় তবে y = foo (x) করুন।

যদি x পূর্ণসংখ্যাগুলির একটি তালিকা হয় তবে y = বার (x) করুন।

এটি কাজ করেছে কারণ foo একটি ডাটাবেস অনুসন্ধান তৈরি করেছে এবং এক্সটি যদি পূর্ণসংখ্যক ছিল এবং কোয়েরিটি যদি সফল হয় তবে x একটি তালিকা তৈরি করে যদি ProgrammingError x হয়।

try/except ব্যবহার try/except এখানে একটি খারাপ পছন্দ:

  1. ব্যতিক্রম নাম, ProgrammingError , প্রকৃত সমস্যাটি ছেড়ে দেয় না (যেটি x পূর্ণসংখ্যা নয়)। যে কি ঘটছে তা চিন্তা করা কঠিন করে তোলে।
  2. ProgrammingError একটি ডাটাবেস কল সময় উত্থাপিত হয়, যা অপ্রয়োজনীয়ভাবে সময় নষ্ট করে। যদি এটি প্রমাণিত হয় যে foo ডাটাবেসটিতে কিছু ব্যতিক্রম লেখার আগে এটি কোনও কিছু লিখেছে বা অন্য কোনও সিস্টেমের অবস্থাকে পরিবর্তিত করে তবে এটি সত্যিই ভয়ঙ্কর হবে।
  3. প্রতিটি ProgrammingError ত্রুটি x দ্বারা একটি তালিকা হওয়ার কারণে এটি অস্পষ্ট। উদাহরণস্বরূপ ধরুন যে foo এর ডাটাবেস অনুসন্ধানে একটি টাইপো আছে। এটি একটি ProgrammingError বাড়াতে পারে। ফলাফলটি হল bar(x) এখন যদি x হয় একটি পূর্ণসংখ্যা। এই রহস্যজনক ব্যতিক্রম বা উত্থাপিত ফলাফল উত্পাদন বাড়াতে পারে।
  4. try/except ব্লক foo ভবিষ্যত বাস্তবায়নে প্রয়োজনীয়তা যোগ করে। যখনই আমরা foo পরিবর্তন করি, তখন আমাদের অবশ্যই এটি কীভাবে পরিচালনাগুলি পরিচালনা করে সে সম্পর্কে চিন্তা করা উচিত এবং এটি নিশ্চিত করা উচিত যে এটি একটি ProgrammingError ত্রুটি ফেলে এবং এটি, একটি AttributeError বা কোনও ত্রুটি নেই বলে মনে করে।

এই বিশেষ ক্ষেত্রে, আপনি সম্পূর্ণরূপে অন্য কিছু ব্যবহার করা উচিত:

x = myDict.get("ABC", "NO_ABC")

সাধারণভাবে, যদিও: আপনি যদি পরীক্ষাটি ঘন ঘন ব্যর্থ হতে চান if ব্যবহার করুন। যদি পরীক্ষাটি কেবল অপারেটিংয়ের চেষ্টা করে এবং এটি ব্যর্থ হয় তবে এটি অপ্রত্যাশিত হয় তবে এটি ব্যবহার try । যদি এই শর্তগুলির মধ্যে একটিও প্রযোজ্য না হয় তবে যা যা পড়তে সহজ তা নিয়ে যান।


যদি আপনি if/else যে ফলাফল যদি try/except উচিত

  • গতি-আপ (উদাহরণস্বরূপ অতিরিক্ত অনুসন্ধান প্রতিরোধ করে)
  • ক্লিনার কোড (কম লাইন / পড়া সহজ)

প্রায়ই, এই হাতে হাতে যান।

গতি আপগুলি

দীর্ঘ তালিকাতে একটি উপাদান খুঁজে বের করার চেষ্টা করার ক্ষেত্রে:

try:
    x = my_list[index]
except IndexError:
    x = 'NO_ABC'

index সম্ভবত তালিকাতে থাকলে সর্বোত্তম বিকল্প ব্যতীত চেষ্টা করুন এবং IndexError সাধারণত উত্থাপিত হয় না। এইভাবে if index < len(mylist) দ্বারা অতিরিক্ত অনুসন্ধানের প্রয়োজন এড়াতে if index < len(mylist)

পাইথন ব্যতিক্রমগুলির ব্যবহারকে উৎসাহিত করে, যা আপনি হ্যান্ডেল করেন Python এ ডাইভ থেকে একটি শব্দ। আপনার উদাহরণটি নীরবভাবে পাস করার পরিবর্তে ব্যতিক্রমটি (চিত্তাকর্ষকভাবে) পরিচালনা করে না, ব্যতিক্রম ব্যতিক্রম শুধুমাত্র ব্যতিক্রমসূচক ক্ষেত্রে পাওয়া যায় না (সুতরাং শব্দ ব্যতিক্রম !)।

ক্লিনার কোড

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

খারাপ (LBYL 'আপনি লাফ দেওয়ার আগে চেহারা') :

#check whether int conversion will raise an error
if not isinstance(s, str) or not s.isdigit:
    return None
elif len(s) > 10:    #too many digits for int conversion
    return None
else:
    return int(str)

ভাল (EAFP: অনুমতি চেয়ে ক্ষমা চাইতে চাইতে সহজ) :

try:
    return int(str)
except (TypeError, ValueError, OverflowError): #int conversion failed
    return None

এটি করার আগে এটি ব্যর্থ হওয়ার কিছু টিপস যদি আপনি এটি করতে ব্যর্থ হন তবে আপনাকে সম্ভবত এটির পক্ষে সমর্থন করা উচিত। সব পরে, ব্যতিক্রম নির্মাণ (তাদের সংশ্লিষ্ট ট্রেসব্যাক সহ) সময় লাগে।

ব্যতিক্রম জন্য ব্যবহার করা উচিত:

  1. অপ্রত্যাশিত জিনিস, বা ...
  2. যেখানে আপনি লজিকের একাধিক স্তরের লাফ দিতে চান (উদাহরণস্বরূপ যেখানে কোনও break আপনাকে যথেষ্ট পরিমাণে পায় না), বা ...
  3. এমন কিছু যেখানে আপনি সঠিকভাবে জানেন না যে পরবর্তী সময়ে ব্যতিক্রম কীভাবে পরিচালনা করা হচ্ছে, বা ...
  4. ব্যর্থতা জন্য সময় এগিয়ে চেক যেখানে জিনিস ব্যয়বহুল (শুধু অপারেশন চেষ্টা করার আপেক্ষিক)

মনে রাখবেন যে মাঝে মাঝে, প্রকৃত উত্তরটি "না" - উদাহরণস্বরূপ, আপনার প্রথম উদাহরণে, আপনাকে যা করতে হবে তা কেবল ডিফল্ট প্রদানের জন্য .get() ব্যবহার .get()

x = myDict.get('ABC', 'NO_ABC')

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

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

উদাহরণস্বরূপ, ধরুন আপনার ছিল:

try:
    x = my_list[index_list[3]]
except IndexError:
    x = 'NO_ABC'

Index_rror index_list বা my_list এর উপাদান পেতে চেষ্টা করার সময় ঘটেছে কিনা সে বিষয়ে কিছুই বলে না।


সাধারণ অর্থের জন্য, আপনি পাইথন-এ আইডিয়ম এবং এন্টি-আইডিয়ম পড়তে বিবেচনা করতে পারেন : ব্যতিক্রমসমূহ

আপনার বিশেষ ক্ষেত্রে, যেমন অন্যরা বলেছেন, আপনি dict.get() ব্যবহার করতে হবে:

পেতে (কী [, ডিফল্ট])

কী যদি অভিধানে কী থাকে তবে কীটির জন্য মানটি ফেরত দিন, অন্যথায় ডিফল্ট। ডিফল্টটি দেওয়া না থাকলে, এটি ডিফল্ট হিসাবে কেউ নয়, যাতে এই পদ্ধতিটি কী-ইরের কখনও বাড়ায় না।





pep