যে কোনও ব্যতিক্রম ধরা সম্পর্কে


695

আমি কীভাবে একটি try/ exceptব্লক লিখতে পারি যা সমস্ত ব্যতিক্রম ধরা পড়ে?


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

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

আপনি চেষ্টা করেছেন : try: whatever() except Exception as e: exp_capture() ?
চার্লি পার্কার 21

উত্তর:


564

আপনি পারবেন কিন্তু আপনার সম্ভবত করা উচিত নয়:

try:
    do_something()
except:
    print "Caught it!"

তবে এটিও এর মতো ব্যতিক্রমগুলি ধরবে KeyboardInterruptএবং আপনি সাধারণত তা চান না, তাই না? আপনি অবিলম্বে এই ব্যতিক্রমটি পুনরায় উত্থাপন না করা - ডক্স থেকে নিম্নলিখিত উদাহরণটি দেখুন :

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except IOError as (errno, strerror):
    print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
    print "Could not convert data to an integer."
except:
    print "Unexpected error:", sys.exc_info()[0]
    raise

30
সম্ভাব্য কার্যসংক্রান্ত: effbot.org/zone/stupid-exceptions-keyboardinterrupt.htm
Mikel

15
আপনার শেষ বিবৃতিটি সত্য নয়, আপনার স্পষ্টভাবে except Exception:খালি বলতে হবে আপনার সেখানে থাকা ব্যতীত বেসএক্সেপশনও পাবেন।
পাইকলার

7
আপনি সত্যিই stderr মুদ্রণ করা উচিত।
nyuszika7h

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

26
আমার কাছে কী অদ্ভুত লাগছে তা হ'ল হাঁসের টাইপিংয়ের ভাষায় যেখানে আপনি উদাহরণের ভেরিয়েবলগুলি ঘোষণা করেন না, হঠাৎ এটি আপনার ব্যতিক্রমগুলি সমস্ত টাইপ না করার বিষয়ে খুব হতাশ। হুম!
আলোকচ্ছটা

833

খালি except:দফা ব্যতীত (যা অন্যেরা বলেছে আপনার ব্যবহার করা উচিত নয়), আপনি কেবল ধরতে পারেন Exception:

import traceback
import logging

try:
    whatever()
except Exception as e:
    logging.error(traceback.format_exc())
    # Logs the error appropriately. 

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

except Exceptionখালি খালি করার সুবিধাটি exceptহ'ল এটি ব্যাতিক্রমী কিছু ব্যতিক্রম যা একেবারেই স্পষ্টতই ধরা দেয় KeyboardInterruptএবং SystemExit: যদি আপনি সেগুলি ধরেন এবং গ্রাস করেন তবে কারও পক্ষে আপনার স্ক্রিপ্ট থেকে বেরিয়ে আসা আপনার পক্ষে শক্ত হয়ে উঠতে পারে।


আমার মনে একই জিনিস ছিল, তবে এগুলি একটি অসুবিধা, মনে করুন একবার ধরা পড়লে এগুলি দুটি ত্রুটি এবং আপনি কেবল মুদ্রণ করা ছাড়া আপনি চেষ্টা ব্লক থেকে বেরিয়ে যাবেন এবং আপনি দ্বিতীয় ত্রুটিটি কখনই জানতে পারবেন না .. ।

6
যে কেউ ভাবছেন, আমার প্রত্যাশার সম্পূর্ণ বিপরীতে এটি কমপক্ষে পাইথন ২.x তে অন্তর্নিহিত সাব-ক্লাসিংয়ের জিনিসগুলি যেমন ইনটসের মতো ধরবে still
জোসেফ গারভিন 22

5
@ জোসেফগারভিন, এটি ভুল, অর্থাৎ এটি সাব-ক্লাস না করে এমন "অ-ব্যতিক্রমগুলি" ধরবে না Exception। মনে রাখবেন যে intব্যতিক্রম হিসাবে একটি উত্থাপন অসম্ভব , এবং এটি করার চেষ্টা একটি TypeErrorব্যতিক্রম উত্থাপন করে , যা except Exceptionএ জাতীয় ক্ষেত্রে আবদ্ধ বিধি দ্বারা ধরা পড়বে । অন্যদিকে, একটি পুরানো ধাঁচের বর্গ উত্থাপিত হতে পারে এবং একটি "অ ব্যতিক্রম" যে উপশ্রেণী না হিসেবে যোগ্যতা Exception- এই করবে একটি খালি হাতে ক্যাচ করা exceptদফা কিন্তু না একটি দ্বারা except Exceptionদফা।
যোয়েল

4
@ জোসেফগারভিন এই ব্লগের এন্ট্রিটি দেখুন: chris-lamb.co.uk/posts/no-one-expects-string-literal-exception এই বিষয়ে আমি @ ইয়য়েলের সাথে রয়েছি, আপনার পরীক্ষাটি কেবল মুখোশধারীTypeError
ডানকান

2
@ চর্লিপার্কার তাদের ধরতে কোনও ভুল নেই যদি আপনি যা চান তা কিন্তু আপনি বেশিরভাগই করেন না। কল করার sys.exit()অর্থ হ'ল আপনি অ্যাপটির সমাপ্তি আশা করে তবে আপনি যদি সিস্টেমএক্সিট ধরেন তবে তা হবে না। একইভাবে আপনি যদি কোনও চলমান স্ক্রিপ্টে নিয়ন্ত্রণ-সি-তে আঘাত করেন (উইন্ডোজগুলিতে Ctrl-Break) আপনি প্রোগ্রামটি বন্ধ হয়ে যাওয়ার আশা করছেন, ত্রুটিটি ধরা এবং চালিয়ে যাবেন না। আপনি যদি বিদ্যমানতার আগে ক্লিনআপ করতে চান তবে আপনি উভয় / উভয়ই ধরতে পারেন।
ডানকান

100

সাধারণ ব্যতিক্রমগুলি পরিচালনা করতে আপনি এটি করতে পারেন

try:
    a = 2/0
except Exception as e:
    print e.__doc__
    print e.message

8
এটি সমস্ত ব্যতিক্রমগুলি ধরতে পারে না, কারণ সমস্ত ব্যাতিক্রমের জন্য বেস শ্রেণিটি বেসএক্সেপশন এবং আমি ব্যতিক্রমী শ্রেণীর পরিবারে নয় এমন প্রযোজনা কোডের মুখোমুখি হয়েছি। এই সম্পর্কে বিস্তারিত জানার জন্য ডকস.পাইথন.আর. / 3 / লাইব্রেরি / দেখুন দেখুন ।
ডিডি

4
এটি সমস্ত ব্যতিক্রম ধরা দেয় না।
অ্যান্ডি_আনাদিডি̷

6
প্রযুক্তিগতভাবে, এটি সমস্ত নন-সিস্টেম-বহির্গমন ব্যতিক্রমগুলি ধরা উচিত। @ ডাই লিঙ্কযুক্ত ডক্স থেকে: " ব্যতিক্রম ব্যাক এক্সেপশন: সমস্ত অন্তর্নির্মিত ব্যতিক্রমগুলির জন্য বেস ক্লাস। এটি ব্যবহারকারী-সংজ্ঞায়িত শ্রেণীর দ্বারা সরাসরি উত্তরাধিকারী হওয়ার অর্থ নয় (তার জন্য ব্যতিক্রম ব্যবহার করুন)"। আপনি যদি এমন কোডের সাথে কাজ করছেন যা এটিকে উপেক্ষা করে না, বা আপনাকে সিস্টেম-বহির্গমন ব্যতিক্রমগুলি ধরা দরকার, উপরেরটি ব্যবহার করা ঠিক হবে।
পিটার ক্যাসেটটা

@ পিটারক্যাসেটটা কখন ব্যতিক্রম ব্যতীত সিস্টেম ধরতে চাইবে? এটিকে প্রশ্নটির সাধারণ থ্রেড বলে মনে হচ্ছে যে আমরা এগুলি ধরতে চাই না, তবে কেন আমি তা বুঝতে পারি না। সাধারণত কেন হয় না?
চার্লি পার্কার

68

সমস্ত সম্ভাব্য ব্যতিক্রম ধরতে, ধরুন BaseException। এটি ব্যতিক্রম শ্রেণিবিন্যাসের শীর্ষে:

পাইথন 3: https://docs.python.org/3.5/library/exception.html#exception- ইতিহাস

পাইথন ২.7: https://docs.python.org/2.7/library/exception.html#exception- ইতিহাস

try:
    something()
except BaseException as error:
    print('An exception occurred: {}'.format(error))

তবে অন্যান্য লোকেরা যেমন উল্লেখ করেছে, আপনার সাধারণত এটির প্রয়োজন হয় না, কেবল নির্দিষ্ট ক্ষেত্রে।


1
Ctrl-C চাপার পরে দীর্ঘমেয়াদী কাজের অগ্রগতি বাঁচানোর ইচ্ছা কি অস্বাভাবিক?
বলপয়েন্টবেন 15

54

খুব সহজ উদাহরণ, এখানে পাওয়া একটি অনুরূপ:

http://docs.python.org/tutorial/errors.html#defining-clean-up-actions

আপনি যদি সমস্ত ব্যতিক্রমগুলি ধরার চেষ্টা করছেন, তবে আপনার সমস্ত কোড "প্রিন্ট করুন" স্টেটমেন্টের মধ্যে রাখুন, এমন একটি ক্রিয়া সম্পাদন যা একটি ব্যতিক্রম ছুঁড়ে ফেলতে পারে "

try:
    print "Performing an action which may throw an exception."
except Exception, error:
    print "An exception was thrown!"
    print str(error)
else:
    print "Everything looks great!"
finally:
    print "Finally is called directly after executing the try statement whether an exception is thrown or not."

উপরের উদাহরণে, আপনি এই ক্রমে আউটপুট দেখতে পাবেন:

1) একটি ক্রিয়া সম্পাদন যা একটি ব্যতিক্রম ছুঁড়ে দিতে পারে।

2) অবশেষে চেষ্টা করা হয় কোনও ব্যতিক্রম ছুঁড়ে দেওয়া হয় বা না তা চেষ্টা করে স্টেট স্টেটমেন্ট কার্যকর করার পরে সরাসরি বলা হয়।

3) "একটি ব্যতিক্রম নিক্ষেপ করা হয়েছিল!" বা "সবকিছু দুর্দান্ত দেখাচ্ছে!" ব্যতিক্রম ছুঁড়েছিল কিনা তার উপর নির্ভর করে।

আশাকরি এটা সাহায্য করবে!


26

পাইথন ৩.০ এবং এরপরের সাথে বিশেষত এটি করার একাধিক উপায় রয়েছে

পদ্ধতির ঘ

এটি সহজ পদ্ধতির তবে প্রস্তাবিত নয় কারণ আপনি ঠিক কী কোডের লাইনটি ব্যতিক্রমটি ছুঁড়ে ফেলছেন তা ঠিক জানেন না:

def bad_method():
    try:
        sqrt = 0**-1
    except Exception as e:
        print(e)

bad_method()

পদ্ধতির ঘ

এই পদ্ধতির প্রস্তাবিত কারণ এটি প্রতিটি ব্যতিক্রম সম্পর্কে আরও বিশদ সরবরাহ করে। এটা অন্তর্ভুক্ত:

  • আপনার কোডের জন্য লাইন নম্বর
  • ফাইলের নাম
  • আরও ভার্বোজ পদ্ধতিতে আসল ত্রুটি

একমাত্র ত্রুটি ট্র্যাকব্যাকটি আমদানি করা দরকার।

import traceback

def bad_method():
    try:
        sqrt = 0**-1
    except Exception:
        print(traceback.print_exc())

bad_method()

21

পাইথন ২.7 এ ব্যতিক্রমের নাম থাকলে পরীক্ষার জন্য আমি এই ছোট্ট কৌশলটি সন্ধান করেছি। কখনও কখনও আমি কোডটিতে নির্দিষ্ট ব্যতিক্রমগুলি পরিচালনা করেছি, সুতরাং নামটি হ্যান্ডলড ব্যতিক্রমগুলির তালিকার মধ্যে রয়েছে কিনা তা দেখার জন্য আমার একটি পরীক্ষার প্রয়োজন হয়েছিল।

try:
    raise IndexError #as test error
except Exception as e:
    excepName = type(e).__name__ # returns the name of the exception

2
try:
    whatever()
except:
    # this will catch any exception or error

এটি উল্লেখ করার মতো এটি যথাযথ পাইথন কোডিং নয়। এটি আপনাকে ধরতে নাও পারে এমন অনেকগুলি ত্রুটি ধরবে।


অন্যান্য কিছু উত্তরে উল্লিখিত সমস্ত ব্যাতিক্রমকে ক্যাচ না করে কেবল ব্যবহার করুন। আপনাকে এই উদ্দেশ্যে বেসএক্সেপশন ব্যবহার করতে হবে তবে আপনি যেমন বলেছিলেন, কারওর মতো এই ব্যতিক্রমগুলি ধরা উচিত নয়। আমার ধারণা, উন্নয়নের সময় বাদে যদি আরও বেশি দানাদার যোগ করা হয় তবে লক্ষ্যটি আমার মনে হয় না ...
পাইগ্লাউথন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.