পাইথনে কীভাবে ব্যতিক্রম বার্তা পাওয়া যায়


97

পাইথনের স্ট্যান্ডার্ড লাইব্রেরির উপাদানগুলি থেকে ব্যতিক্রম বার্তা পাওয়ার সর্বোত্তম উপায় কী?

আমি লক্ষ্য করেছি যে কিছু ক্ষেত্রে আপনি এটি messageক্ষেত্রের মাধ্যমে এটি পেতে পারেন :

try:
  pass
except Exception as ex:
  print(ex.message)

তবে কিছু ক্ষেত্রে (উদাহরণস্বরূপ, সকেটের ত্রুটির ক্ষেত্রে) আপনাকে এই জাতীয় কিছু করতে হবে:

try:
  pass
except socket.error as ex:
  print(ex)

আমি অবাক হয়েছি এই পরিস্থিতিতে বেশিরভাগ ক্ষেত্রে কোনও স্ট্যান্ডার্ড উপায় রয়েছে?


4
আপনি দুটি পৃথক জিনিসকে বিবাদ দিচ্ছেন - এটির except Foo as bar:মতোই except Foo, bar:(পূর্ববর্তীটি আরও নতুন বাদে এবং 3.x এ কাজ করা চালিয়ে যাবে), তবুও ত্রুটিটি কোনও messageবৈশিষ্ট্য নিয়ে আসে বা না পৃথক।
jonrsharpe

4
@ ফ্রোজেনহার্ট আপনি কি জিজ্ঞাসা করছেন যে .messageকোনও ত্রুটির জন্য অ্যাক্সেস করা আদর্শ উপায় কিনা ?
আনন্দ এস কুমার

আপনার দ্বিতীয় উদাহরণটি print(msg)কেবল একটি শর্টকাটprint(str(msg))
সালো

@ আনন্দ এস কুমার ইয়েপ। এটি কোনও ক্ষেত্রে কাজ করবে?
ফ্রোজেন হার্ট

4
আমি বিশ্বাস করি অ্যাক্সেসিং অবমূল্যায়ন messageকরা হয়েছে।
জোনাথন রেইনার্ট

উত্তর:


94

যদি আপনি অন্তর্নির্মিত ত্রুটিগুলির জন্য ডকুমেন্টেশনটি দেখেন তবে আপনি দেখতে পাবেন যে বেশিরভাগ Exceptionশ্রেণি তাদের প্রথম যুক্তিকে একটি messageগুণ হিসাবে চিহ্নিত করে । তাদের সবাই যদিও না।

উল্লেখযোগ্যভাবে, EnvironmentError(সাবক্লাস সহ IOErrorএবং OSError) এর প্রথম আর্গুমেন্ট রয়েছে errno, দ্বিতীয়টি strerror। নেই message... strerrorমোটামুটি যা সাধারণত একটি হতে পারে তার সাথে সাদৃশ্যপূর্ণ message

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

আমি মনে করি এটি হ্যান্ডল করার সঠিক Exceptionউপায়টি হ'ল আপনি যে নির্দিষ্ট সাবক্লাসগুলি ধরতে চান তা চিহ্নিত করা এবং তারপরে একটি দিয়ে সমস্ত কিছুর পরিবর্তে কেবল তাদেরই ধরা except Exception, তারপরে আপনি চান সুনির্দিষ্ট সাবক্লাসের দ্বারা নির্ধারিত বৈশিষ্ট্যগুলি ব্যবহার করুন।

আপনার যদি printকিছু অবশ্যই করা থাকে তবে আমি মনে করি যে ধরা পড়েছে সেটিকে Exceptionছাপানোই আপনি চান যা করতে চান, এর কোনও messageবৈশিষ্ট্য আছে কি নেই তা সম্ভবত সম্ভব ।

আপনি চাইলে এই বার্তাটির বৈশিষ্ট্যটিও পরীক্ষা করে দেখতে পারেন, তবে এটি অগোছালো বলে মনে হচ্ছে বলে আমি সত্যিই এটি প্রস্তাব করব না:

try:
    pass
except Exception as e:
    # Just print(e) is cleaner and more likely what you want,
    # but if you insist on printing message specifically whenever possible...
    if hasattr(e, 'message'):
        print(e.message)
    else:
        print(e)

উত্তর করার জন্য ধন্যবাদ. ন্যায়বিচারের str(ex)পরিবর্তে ব্যবহারের কোনও বিশেষ কারণ আছে কি ex?
ফ্রোজেনহার্ট

4
@ ফ্রোজেন হার্ট - print()স্বয়ংক্রিয়ভাবে str()আপনার জন্য কল করে । এটিকে ম্যানুয়ালি নিজেকে কল করার কোনও কারণ নেই, যদিও এটি str()কোনও ক্ষতিহীন নয় যেহেতু স্ট্রিংয়ে কল করার পরে কেবল স্ট্রিংই ফিরে আসবে।
আর্টঅফ ওয়ারফেয়ার

4
@ আর্টঅফ ওয়ারফেয়ার আমার মতে str()বার্তাটি টাইপ করলে সমস্যা হতে পারে unicode
kratenko

34

@ আর্টফোয়ারফেয়ারের দেওয়া উত্তরের উন্নতির জন্য , আমি messageএট্রিবিউটটি যাচাই করতে এবং এটি মুদ্রণ করতে বা Exceptionঅবজেক্টটিকে ফ্যালব্যাক হিসাবে মুদ্রণের জন্য একটি ভাল উপায় বিবেচনা করছি ।

try:
    pass 
except Exception as e:
    print getattr(e, 'message', repr(e))

কলটি reprisচ্ছিক, তবে কিছু ব্যবহারের ক্ষেত্রে এটি প্রয়োজনীয় বলে মনে করি।


আপডেট # 1:

@ ম্যাডফিসিসিস্টের মন্তব্যের পরে , কেন কলটি প্রয়োজনীয় reprহতে পারে তার একটি প্রমাণ এখানে । আপনার দোভাষীতে নিম্নলিখিত কোডটি চালানোর চেষ্টা করুন:

try:
    raise Exception 
except Exception as e:
    print(getattr(e, 'message', repr(e)))
    print(getattr(e, 'message', str(e)))

আপডেট # 2:

পাইথন ২.7 এবং 3.5 এর জন্য নির্দিষ্ট একটি ডেমো এখানে রয়েছে: https://gist.github.com/takwas/3b7a6edddef783f2abddffda1439f533


4
getattrযদি পাস করা বস্তুর অনুরোধক বৈশিষ্ট্য না থাকে তবে একটি ব্যতিক্রম ছুঁড়ে। আপনি যে ভালো কিছু করতে চেয়েছিলেন, আমি মনে করি আপনার জন্য ঐচ্ছিক তৃতীয় যুক্তি ব্যবহার করা উচিত getattr, এভাবে: print getattr(e, 'message', e)। আমি যা করেছি তার চেয়ে বিতর্কিতভাবে ভাল। অন্য বিকল্প হবে print(e.message if hasattr(e, 'message') else e)
আর্টঅফ ওয়ারফেয়ার

4
আপনি প্রায় অবশ্যই strপরিবর্তে চাইবেন repr
ম্যাড পদার্থবিদ

4
তুলনায় str, reprকেবল শ্রেণীর নাম যুক্ত করুন। ব্যবহারের পরিবর্তে repr, আমি ব্যবহারের প্রস্তাব দেব print('{e.__class__.__name__}: {e}'.format(e=e))। মুদ্রণ আউটপুটটি ক্লিনার এবং নিজেই উত্থাপনের ফলাফলকে মেনে চলে।
কাদি

4
উপরে উপর ভিত্তি করে, আমি সবচেয়ে দরকারী আমাকে হতে পাওয়া যায়নি'{e.__class__.__module__}.{e.__class__.__name__}: {e}'
দয়া

4
ধন্যবাদ !! repr(e)আপাতত একমাত্র সমাধান ছিল যা আমাকে নির্দিষ্ট পরিস্থিতিতে আমি যে ত্রুটিটি ধরছিলাম তার নূন্যতম পরিমাণে তথ্য মুদ্রণ করতে সহায়তা করেছিল। repr(e)ফলন KeyError(0,)(ত্রুটিটি যা হ'ল), যখন str(e)বা যথাক্রমে e.messageকেবল 0বা কিছুই পাওয়া যায় না।
ফ্লোরিয়ানএইচ

0

আমারও একই সমস্যা ছিল। আমি মনে করি লগ.এক্সসেপশন ব্যবহার করা সবচেয়ে ভাল সমাধান, যা স্বয়ংক্রিয়ভাবে স্ট্যাক ট্রেস এবং ত্রুটির বার্তাটি মুদ্রণ করবে, যেমন:

try:
    pass
    log.info('Success')
except:
    log.exception('Failed')

4
কী log? আমি কেবল import logপাইথন ২.7.১৩ এ চেষ্টা করেছি এবং একটি বার্তা পেয়েছি যে সেই নামের কোনও মডিউল নেই। এটি কি আপনি কিছু দিয়ে যুক্ত করেছেন pipবা এটি পাইথনের একটি নতুন সংস্করণে যুক্ত হয়েছিল (আমি জানি, আমি জানি, পাইথন 3 এ আমার আপডেট করা দরকার ... সেন্টোস ডিফল্টরূপে পাইথন 2 দিয়ে শিপিং বন্ধ করার সাথে সাথেই আমি এটি করব ...)
আর্টঅফ ওয়ারফেয়ার

6
তিনি / তিনি সম্ভবত অজগর থেকে লগিং মডিউলটি ব্যবহার করছেন এবং তারপরে একটি লগটিকে লগ ভেরিয়েবল হিসাবে ইনস্ট্যান্ট করছেন। import logging। nlog = logging.getLogger(__name__)
জোসেপাস

0

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

try:
   # do something that may raise an AuthException
except AuthException as ex:
   if ex.args[0] == "Authentication Timeout.":
      # handle timeout
   else:
      # generic handling
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.