আমি কি সর্বদা `বাকী বিবৃতিতে একটি ব্যতিক্রম প্রকার নির্দিষ্ট করতে পারি?


96

পাইচার্ম আইডিই ব্যবহার করার সময় except:কোনও ব্যাতিক্রম ছাড়াই ব্যবহার আইডিই থেকে এই ব্যতিক্রম ধারাটি অনুস্মারককে ট্রিগার করে Too broad

আমি কি এই পরামর্শ উপেক্ষা করা উচিত? বা ব্যতিক্রমটি সর্বদা নির্দিষ্ট করা কি পাইথোনিক?


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

উত্তর:


93

সুস্পষ্ট ব্যতিক্রম প্রকারটি নির্দিষ্ট করা প্রায় সর্বদা ভাল। যদি আপনি একটি নগ্ন except:ধারা ব্যবহার করেন তবে আপনি যেটি ধরার আশা করছেন তা ব্যতীত আপনি ব্যতিক্রমগুলিও শেষ করতে পারেন - এটি বাগগুলি আড়াল করতে পারে বা যখন আপনি প্রত্যাশা করেন না তখন প্রোগ্রামগুলি ডিবাগ করা আরও শক্ত করে তোলে।

উদাহরণস্বরূপ, আপনি যদি একটি ডাটাবেসে সারি সন্নিবেশ করিয়ে থাকেন তবে আপনি একটি ব্যতিক্রম ধরতে চাইতে পারেন যা সারিটি ইতিমধ্যে উপস্থিত রয়েছে তা নির্দেশ করে তাই আপনি একটি আপডেট করতে পারেন।

try:
    insert(connection, data)
except:
    update(connection, data)

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

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

এই সমস্তটির একটি প্রকৃতপক্ষে হ'ল আপনার কোডটি কখনই করা উচিত নয় raise Exception('some message')কারণ এটি ক্লায়েন্ট কোডটি ব্যবহার করতে বাধ্য করে except:(বা except Exception:যা প্রায় হিসাবে খারাপ)। আপনি যে সমস্যাটি সিগন্যাল করতে চান তার সাথে সম্পর্কিত একটি ব্যতিক্রম নির্দিষ্ট করা উচিত (সম্ভবত কিছু বিল্ট-ইন ব্যতিক্রম সাবক্লাসের মতো উত্তরাধিকারসূতী ValueErrorবা TypeError)। অথবা আপনার একটি নির্দিষ্ট অন্তর্নির্মিত ব্যতিক্রম উত্থাপন করা উচিত। এটি আপনার কোডের ব্যবহারকারীদের কেবলমাত্র ব্যতিক্রমগুলি পরিচালনা করতে চায় সে বিষয়ে যত্নশীল হতে সক্ষম করে।


7
+1 খুব সত্য। উদাহরণ সহ আরও মজাদার: except:এছাড়াও ধরা পড়ে (অন্যান্য অনেক কিছুর মধ্যেও) NameErrorএবং AttributeErrorতাই, আপনি যদি tryব্লকের কোনও কিছু ভুল বানান করে থাকেন (যেমন আপনার "সন্নিবেশ" ফাংশনটি আসলে বলা হয় insert_oneকারণ কেউ তার সামঞ্জস্যতার ততটা মূল্য দেয়নি), এটি সর্বদা নিঃশব্দে চেষ্টা করে update()

4
সুতরাং যখন আপনার কোনও ব্যতিক্রম বর্তমান কল সাইটের উপরে না ফেলেছে তা নিশ্চিত করার দরকার কী? অর্থাৎ - আমি ছুঁড়ে ফেলার পূর্বে যে সমস্ত সুনির্দিষ্ট ব্যতিক্রমগুলি পূর্বে দেখতে পাচ্ছিলাম তা আমি ধরে ফেলেছি, এখন আমাকে যুক্ত করতে হবে "যদি এই জিনিসটি আমি নিক্ষেপ হওয়ার কথা ভাবি না তবে এটি চলমান মৃত্যুদন্ডের প্রসঙ্গটি মেরে ফেলার আগে আমাকে এটি লগ করা দরকার" (যেমন main())?
অ্যাডাম পার্কিন

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

4
@ ডেলানন: এর চেয়েও খারাপ। except Exception:ধরবে NameErrorএবং AttributeErrorখুব। যা except:এতটা খারাপ করে তোলে তা হ'ল এটি এমন কোনও জিনিসকে ধরে ফেলে যার কোনও ব্যবসায় ধরা পড়ে না, যেমন SystemExit(আপনি যখন ফোন করবেন exitবা উত্থাপন করেছিলেন sys.exitএবং এখন আপনি একটি নির্ধারিত প্রস্থানকে বাধা দিয়েছেন) এবং KeyboardInterrupt(আবার যদি ব্যবহারকারী আঘাত করে তবে Ctrl-Cআপনি সম্ভবত এটি চান না কেবল তাদের তুচ্ছ করার জন্য দৌড়াতে থাকুন)। কেবল পরের ব্যক্তিগুলি ধরার জন্য কোনও আসল ধারণা দেয় এবং এটি স্পষ্টভাবে ধরা উচিত। কমপক্ষে except Exception:এই দুজনকে স্বাভাবিকভাবে প্রচার করতে দেয়।
শ্যাডোর্যাঞ্জার

39

দোভাষী আপনাকে যে পরামর্শ দেয় তা আপনার অবহেলা করা উচিত নয়।

থেকে PEP -8 পাইথন জন্য স্টাইল গাইড:

ব্যতিক্রমগুলি ধরার সময়, যখনই সম্ভব খালি ব্যবহার ব্যতিরেকে নির্দিষ্ট ব্যতিক্রমগুলি উল্লেখ করুন:

উদাহরণস্বরূপ, ব্যবহার করুন:

 try:
     import platform_specific_module 
 except ImportError:
     platform_specific_module = None 

একটি খালি ব্যতীত: ধারাটি সিস্টেমএক্সিট এবং কীবোর্ড আন্তঃব্যক্ত ব্যতিক্রমগুলি ধরবে, নিয়ন্ত্রণ-সি এর সাথে কোনও প্রোগ্রামকে বাধা দেওয়া আরও শক্ত করে তোলে এবং অন্যান্য সমস্যার ছদ্মবেশ ধারণ করতে পারে। আপনি যদি সমস্ত ব্যতিক্রমগুলি সিগন্যাল প্রোগ্রামের ত্রুটিগুলি ধরতে চান তবে ব্যতিক্রম ব্যতীত ব্যবহার করুন: (বেস ব্যাক্সেস্পেশন ব্যতীত খালি ছাড়া)

থাম্বের একটি ভাল নিয়ম হ'ল দুটি ব্যতিরেকে 'খালি' ব্যতীত ব্যবহারের সীমাবদ্ধ করা:

যদি ব্যতিক্রম হ্যান্ডলারটি মুদ্রণ করে বা ট্রেসব্যাক লগ ইন করে; কমপক্ষে ব্যবহারকারী সচেতন হবেন যে একটি ত্রুটি ঘটেছে। কোডটিতে যদি কিছু পরিষ্কার করার কাজ করা দরকার হয় তবে তারপরে ব্যতিক্রমটি উপরের দিকে বাড়িয়ে প্রচার করতে দেয়। চেষ্টা করুন ... শেষ পর্যন্ত এই কেসটি হ্যান্ডেল করার আরও ভাল উপায় হতে পারে।



9

পাইথনের কাছে এটি স্পিফিক নয়।

ব্যতিক্রমগুলির পুরো বিষয়টি হ'ল সমস্যাটি যতটা সম্ভব ঘটেছে তার কাছাকাছিভাবে মোকাবেলা করা।

সুতরাং আপনি এমন কোডটি রেখেছেন যা ব্যতিক্রমী সিরামাস্তে সমস্যাটি এবং ট্রিগারটিকে একে অপরের কাছে "পরবর্তী" করতে পারে।

জিনিসটি হ'ল আপনি কোনও ব্যতিক্রম কোডের দ্বারা ছুঁড়ে দেওয়া সমস্ত ব্যতিক্রমগুলি জানতে পারবেন না। আপনারা কেবলমাত্র এটিই জানেন যে যদি এটির কোনও বললে কোনও ফাইল ব্যতিক্রম না পাওয়া যায় তবে আপনি এটি আটকে রাখতে পারেন এবং ব্যবহারকারীকে এটির জন্য অনুরোধ করতে পারে যা ফাংশনটি করে বা বাতিল করে দেয়।

যদি আপনি সেটিকে ধরতে চেষ্টা করেন তবে আপনার ফাইলের রুটিনে যে সমস্যা ছিল না কেন (কেবলমাত্র পঠন, অনুমতি, ইউএসি, সত্যিকারভাবে পিডিএফ ইত্যাদি নয়), প্রত্যেকে আপনার ফাইলটিতে ফেলবে যা ধরা পড়ে না এবং আপনার ব্যবহারকারী চিৎকার করছে "তবে এটি সেখানে আছে, এই কোডটি বকাঝকা"

এখন বেশ কয়েকটি পরিস্থিতি রয়েছে যেখানে আপনি হয়ত সব কিছু ধরতে পারেন তবে সেগুলি সচেতনভাবে বেছে নেওয়া উচিত।

তারা ধরা পড়েছে, কিছু স্থানীয় ক্রিয়া পূর্বাবস্থায় ফেলেছে (যেমন কোনও উত্স তৈরি করা বা লক করা (উদাহরণস্বরূপ লেখার জন্য ডিস্কে একটি ফাইল খোলার), তারপরে আপনি আবারও ব্যতিক্রম নিক্ষেপ করতে পারেন, উচ্চতর স্তরে মোকাবেলা করার জন্য)

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

দ্রষ্টব্য আপনি যদি উপরের কাজটি করেন তবে আমি কোনও প্রকারের ব্যতিক্রম লগিংয়ের প্রস্তাব দিতে পারছি না, উদাহরণস্বরূপ যথেষ্ট লগ লন্ডের চেষ্টা করুন।


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

4
"কেন এটি ভুল হয়ে গেছে তা আপনি চিন্তা করেন না" এর জন্য +1। আমি কোডের একক লাইনের আশেপাশে বেশ কয়েকটি জায়গায় এটি ব্যবহার করছি যেখানে আমি কোনও URL থেকে তারিখ / সময় পার্স করি। তৃতীয় পক্ষের তারিখ / সময় পার্সিংয়ের পাঠাগারটি যে সমস্ত ব্যতিক্রম ছুঁড়ে ফেলতে পারে তার সবগুলি তালিকাভুক্ত করে না (আমি স্ট্যান্ডার্ড ভ্যালু এরির ছাড়াও ওভারফ্লো ইরির এবং টাইপএরর খুঁজে পেয়েছি, তবে সম্ভবত আরও রয়েছে), এবং যাইহোক আমি সত্যিই কেন চিন্তা করি না কেন একটি ব্যতিক্রম ছুঁড়ে দেওয়া হয়েছিল, আমি কেবল ব্যবহারকারীকে ফিরে যুক্তিসঙ্গত ত্রুটি বার্তা সরবরাহ করতে চাই যে তারিখ / সময়টির সাথে কিছু ভুল আছে।
মাইকেল রডবি

3

আপনি এটির সাথে উদাহরণস্বরূপ কন্ট্রোল-সিও ধরতে পারবেন, সুতরাং যদি আপনি এটি আবার "নিক্ষেপ" না করেন তবে এটি করবেন না। তবে, সেক্ষেত্রে আপনার পরিবর্তে "অবশেষে" ব্যবহার করা উচিত।


3

সর্বদা ব্যতিক্রম প্রকার নির্দিষ্ট অনেক ধরনের ধরতে চাই না, মত SyntaxError, KeyboardInterrupt, MemoryErrorইত্যাদি


4
except Exception:উপরের প্রকারগুলি যা আমরা ধরতে চাই না তা ব্যবহার করে ব্যবহার করব?
হর্সওলফ্যাট


4
@ হর্সওলফ্যাট: except Exceptionক্যাচ করে SyntaxErrorএবং MemoryErrorকারণ এটি তাদের বেস ক্লাস। KeyboardInterrupt, SystemExit(উত্থাপিত sys.exit()) ধরা পড়ে না (তারা অবিলম্বে বেসএক্সেপশন সাবক্লাস)
jfs

মনে হয় এটি তখন আদর্শ নয় - আরও সুনির্দিষ্টভাবে উল্লেখ করা ভাল।
হর্সওলফ্যাট

3

এখানে আমি যেখানে টাইপ না করে ব্যবহার করি সেগুলি এখানে

  1. দ্রুত এবং নোংরা প্রোটোটাইপিং

চেক না করা ব্যতিক্রমগুলির জন্য এটি আমার কোডের প্রধান ব্যবহার

  1. শীর্ষ স্তরের প্রধান () ফাংশন, যেখানে আমি প্রতিটি অপ্রকাশিত ব্যতিক্রম লগ করি

আমি সর্বদা এটি যুক্ত করি, যাতে উত্পাদন কোড স্ট্যাকট্রেসগুলি না ছড়িয়ে দেয়

  1. অ্যাপ্লিকেশন স্তর মধ্যে

আমার এটি করার দুটি উপায় রয়েছে:

  • এটি করার প্রথম উপায়: যখন একটি উচ্চ স্তরের স্তর একটি নিম্ন স্তরের ফাংশন কল করে, এটি "শীর্ষ" নিম্ন স্তরের ব্যতিক্রমগুলি পরিচালনা করতে টাইপযুক্ত ব্যতিক্রমগুলিতে কলগুলিকে আবৃত করে। তবে আমি নিম্ন স্তরের ফাংশনগুলিতে নিরস্ত্র নিম্ন স্তরের ব্যতিক্রমগুলি সনাক্ত করতে স্টেটমেন্ট ব্যতীত জেনেরিক যুক্ত করি।

আমি এটি এটিকে পছন্দ করি, কোন ব্যতিক্রমগুলি যথাযথভাবে ধরা উচিত ছিল তা সনাক্ত করা আমার পক্ষে সহজ হয়: নিম্ন স্তরের ব্যতিক্রম যখন উচ্চ স্তরের দ্বারা লগ হয় তখন আমি সমস্যাটি আরও ভাল দেখতে পাই

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

কিছু সহকর্মীরা এইভাবে পছন্দ করেন, কারণ এটি নিম্ন স্তরের কার্যগুলিতে নিম্ন স্তরের ব্যতিক্রমগুলি রাখে, যেখানে তারা "অন্তর্ভুক্ত"।


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.