উত্তর:
পাইথনে আমি কীভাবে ম্যানুয়ালি ছোঁড়া / আপত্তি তুলব?
সুনির্দিষ্ট ব্যতিক্রমী কনস্ট্রাক্টর ব্যবহার করুন যা শব্দার্থে আপনার সমস্যার সাথে খাপ খায় ।
আপনার বার্তায় নির্দিষ্ট থাকুন, যেমন:
raise ValueError('A very specific bad thing happened.')
জেনেরিক উত্থাপন করা এড়িয়ে চলুন Exception
। এটি ধরার জন্য, আপনাকে অন্য সমস্ত নির্দিষ্ট ব্যতিক্রমগুলি এটিকে সাবক্লাস করে ফেলতে হবে।
raise Exception('I know Python!') # Don't! If you catch, likely to hide bugs.
উদাহরণ স্বরূপ:
def demo_bad_catch():
try:
raise ValueError('Represents a hidden bug, do not catch this')
raise Exception('This is the exception you expect to handle')
except Exception as error:
print('Caught this error: ' + repr(error))
>>> demo_bad_catch()
Caught this error: ValueError('Represents a hidden bug, do not catch this',)
এবং আরও নির্দিষ্ট ক্যাচগুলি সাধারণ ব্যতিক্রমটিকে ধরবে না:
def demo_no_catch():
try:
raise Exception('general exceptions not caught by specific handling')
except ValueError as e:
print('we will not catch exception: Exception')
>>> demo_no_catch()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in demo_no_catch
Exception: general exceptions not caught by specific handling
raise
বিবৃতিপরিবর্তে, সুনির্দিষ্ট ব্যতিক্রমী কনস্ট্রাক্টর ব্যবহার করুন যা শব্দার্থে আপনার সমস্যার সাথে খাপ খায় ।
raise ValueError('A very specific bad thing happened')
যা হাতছাড়াভাবে নির্বিচারে একটি স্বেচ্ছাসেবী সংখ্যক আর্গুমেন্টকে মঞ্জুরি দেয়:
raise ValueError('A very specific bad thing happened', 'foo', 'bar', 'baz')
এই যুক্তিগুলি অবজেক্টের args
বৈশিষ্ট্য দ্বারা অ্যাক্সেস করা হয় Exception
। উদাহরণ স্বরূপ:
try:
some_code_that_may_raise_our_value_error()
except ValueError as err:
print(err.args)
কপি করে প্রিন্ট
('message', 'foo', 'bar', 'baz')
পাইথন ২.২-তে, একটি প্রকৃত message
বৈশিষ্ট্য যুক্ত করা BaseException
হয়েছে ব্যবহারকারীদের সাবক্লাস ব্যতিক্রমগুলিকে উত্সাহিত করার এবং ব্যবহার বন্ধ করতে উত্সাহিত করার পক্ষে args
, তবে আরোগুলির পরিচয় message
এবং মূল অবমূল্যায়ন প্রত্যাহার করা হয়েছে ।
except
ধারাক্লজ ব্যতীত যখন কোনও অভ্যন্তরে থাকে, আপনি চাইবেন, উদাহরণস্বরূপ, লগ করুন যে একটি নির্দিষ্ট ধরণের ত্রুটি ঘটেছে এবং তারপরে পুনরায় উত্থাপন করুন। স্ট্যাক ট্রেস সংরক্ষণ করার সময় এটি করার সর্বোত্তম উপায় হ'ল খালি বিবৃতি বিবরণী ব্যবহার করা। উদাহরণ স্বরূপ:
logger = logging.getLogger(__name__)
try:
do_something_in_app_that_breaks_easily()
except AppError as error:
logger.error(error)
raise # just this!
# raise AppError # Don't do this, you'll lose the stack trace!
আপনি স্ট্যাকট্রেস (এবং ত্রুটির মান) সংরক্ষণ করে রাখতে পারেন sys.exc_info()
তবে এটি আরও বেশি ত্রুটিযুক্ত প্রবণ এবং পাইথন 2 এবং 3 এর মধ্যে সামঞ্জস্যতার সমস্যা রয়েছে , raise
পুনরায় উত্থাপনের জন্য খালি ব্যবহার করতে পছন্দ করেন ।
ব্যাখ্যা করতে - sys.exc_info()
প্রকার, মান এবং ট্রেসব্যাক ফেরত দেয়।
type, value, traceback = sys.exc_info()
এটি পাইথন 2-এর বাক্য গঠন রয়েছে - দ্রষ্টব্য এটি পাইথন 3 এর সাথে সামঞ্জস্যপূর্ণ নয়:
raise AppError, error, sys.exc_info()[2] # avoid this.
# Equivalently, as error *is* the second object:
raise sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]
আপনি যদি চান, আপনার নতুন উত্থানের সাথে কী ঘটে তা আপনি সংশোধন করতে পারেন - উদাহরণস্বরূপ নতুন সেট করা args
:
def error():
raise ValueError('oops!')
def catch_error_modify_message():
try:
error()
except ValueError:
error_type, error_instance, traceback = sys.exc_info()
error_instance.args = (error_instance.args[0] + ' <modification>',)
raise error_type, error_instance, traceback
আরগগুলি সংশোধন করার সময় আমরা পুরো ট্রেসব্যাক সংরক্ষণ করেছি। দ্রষ্টব্য যে এটি সর্বোত্তম অনুশীলন নয় এবং এটি পাইথন 3-তে অবৈধ সিনট্যাক্স (
>>> catch_error_modify_message()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in catch_error_modify_message
File "<stdin>", line 2, in error
ValueError: oops! <modification>
ইন পাইথন 3 :
raise error.with_traceback(sys.exc_info()[2])
আবার: ট্র্যাকব্যাকগুলি ম্যানুয়ালি করে এড়িয়ে চলুন। এটি কম দক্ষ এবং ত্রুটিযুক্ত প্রবণ। এবং যদি আপনি থ্রেডিং ব্যবহার করছেন এবং sys.exc_info
আপনি ভুল ট্রেসব্যাক পেতে পারেন (বিশেষত যদি আপনি নিয়ন্ত্রণ প্রবাহের ক্ষেত্রে ব্যতিক্রম হ্যান্ডলিং ব্যবহার করছেন - যা আমি ব্যক্তিগতভাবে এড়াতে চাইতাম))
পাইথন 3 এ, আপনি ব্যতিক্রমগুলি চেইন করতে পারেন, যা ট্রেসব্যাকগুলি সংরক্ষণ করে:
raise RuntimeError('specific message') from error
সচেতন থাকা:
এগুলি সহজেই লুকিয়ে রাখতে পারে এবং এমনকি উত্পাদন কোডেও code আপনি একটি ব্যতিক্রম বাড়াতে চান, এবং সেগুলি করা একটি ব্যতিক্রম বাড়িয়ে তুলবে, তবে তা নয়!
পাইথন 2 এ বৈধ, তবে পাইথন 3 এ নয় :
raise ValueError, 'message' # Don't do this, it's deprecated!
পাইথনের পুরানো সংস্করণগুলিতে কেবল বৈধ (২.৪ এবং নিম্ন), আপনি এখনও লোককে স্ট্রিং উত্থাপন করতে দেখতে পাবেন:
raise 'message' # really really wrong. don't do this.
সমস্ত আধুনিক সংস্করণে, এটি আসলে একটি বাড়িয়ে তুলবে TypeError
, কারণ আপনি কোনও BaseException
ধরণের উত্থাপন করছেন না । আপনি যদি সঠিক ব্যতিক্রমটি পরীক্ষা না করে থাকেন এবং সমস্যা সম্পর্কে সচেতন এমন কোনও পর্যালোচক না রাখেন তবে এটি উত্পাদন পেতে পারে।
আমি আমার এপিআই এর গ্রাহকদের যদি এটি ভুলভাবে ব্যবহার করে থাকে তবে তাদের সতর্ক করতে ব্যতিক্রমগুলি উত্থাপন করি:
def api_func(foo):
'''foo should be either 'baz' or 'bar'. returns something very useful.'''
if foo not in _ALLOWED_ARGS:
raise ValueError('{foo} wrong, use "baz" or "bar"'.format(foo=repr(foo)))
"আমি উদ্দেশ্য করে একটি ত্রুটি তৈরি করতে চাই, যাতে এটি বাদে চলে যায়"
আপনি আপনার নিজের ত্রুটির প্রকারগুলি তৈরি করতে পারেন, আপনি যদি নিজের অ্যাপ্লিকেশনটির সাথে নির্দিষ্ট কিছু ভুল বলে চিহ্নিত করতে চান তবে কেবল ব্যতিক্রম শ্রেণিবিন্যাসের যথাযথ পয়েন্টটি সাবক্লাস করুন:
class MyAppLookupError(LookupError):
'''raise this when there's a lookup error for my app'''
এবং ব্যবহার:
if important_key not in resource_dict and not ok_to_be_missing:
raise MyAppLookupError('resource is missing, and that is not ok.')
raise sys.exc_info()[0], (sys.exc_info()[1], my_extra_info), sys.exc_info()[2]
আমি যা চাই তা করতে দেখে মনে হচ্ছে এবং আমি এর সাথে কখনও সমস্যায় পড়ি না। তবে এটি হ্যাকিং অনুভব করে এবং এটি কোনও গ্রহণযোগ্য অনুশীলন নয়। একটি ভাল উপায় আছে কি?
Exception
আপনার পিতামাতা শ্রেণীর হিসাবে নেওয়া 4 টি ব্যতিক্রমগুলির মধ্যে একটিও আপনার ব্যবহার করা উচিত নয় - আপনি আরও নির্দিষ্ট কিছু সাবক্লাস করতে পারেন, এবং যদি তা বোঝা যায় তবে তা করা উচিত।
AppError
ব্যতিক্রম ব্যবহার করেন । এটা একটা বিল্ট-ইন এরর মত ব্যবহার করতে ভাল হতে পারেAttributeError
এটি করবেন না । খালি উত্থাপন
Exception
করা একেবারে সঠিক জিনিস নয় ; দেখতে হারুন হল এর চমৎকার উত্তর পরিবর্তে।
এর থেকে বেশি পাইথোনিক পাওয়া যায় না:
raise Exception("I know python!")
দেখা আরও তথ্য চাইলে অজগরটির জন্য উত্থাপন বিবরণী ডক্স দেখুন।
পাইথন 3 এ রেসপন্স ব্যতিক্রমগুলির জন্য 4 টি আলাদা সিনট্যাক্স রয়েছে:
1. raise exception
2. raise exception (args)
3. raise
4. raise exception (args) from original_exception
1. ব্যতিক্রম উত্থাপন বনাম 2. ব্যতিক্রম বাড়া
আপনি যদি raise exception (args)
কোনও ব্যতিক্রম বাড়াতে ব্যবহার args
করেন তবে নীচের উদাহরণে যেমন দেখানো হয়েছে - আপনি ব্যতিক্রম বস্তুটি মুদ্রণ করার পরে মুদ্রণ করা হবে।
#raise exception (args)
try:
raise ValueError("I have raised an Exception")
except ValueError as exp:
print ("Error", exp) # Output -> Error I have raised an Exception
#raise execption
try:
raise ValueError
except ValueError as exp:
print ("Error", exp) # Output -> Error
3.raise
raise
কোনও যুক্তি ছাড়াই বিবৃতিটি সর্বশেষ ব্যতিক্রমটিকে পুনরায় উত্থাপন করে। ব্যতিক্রমটি ধরার পরে যদি আপনাকে কিছু ক্রিয়া সম্পাদন করতে হবে এবং তারপরে এটি আবার উত্থাপন করতে চান তবে এটি কার্যকর। তবে এর আগে যদি ব্যতিক্রম না হয়, raise
বিবৃতি TypeError
ব্যতিক্রম উত্থাপন করে ।
def somefunction():
print("some cleaning")
a=10
b=0
result=None
try:
result=a/b
print(result)
except Exception: #Output ->
somefunction() #some cleaning
raise #Traceback (most recent call last):
#File "python", line 8, in <module>
#ZeroDivisionError: division by zero
৪. অরিজিনাল এক্সসেপশন থেকে ব্যতিক্রম (আরগস) বাড়ান
এই বিবৃতিটি ব্যতিক্রম শৃঙ্খলা তৈরি করতে ব্যবহৃত হয় যাতে অন্য একটি ব্যতিক্রমের প্রতিক্রিয়া হিসাবে উত্থাপিত ব্যতিক্রমটি মূল ব্যতিক্রমের বিশদটি ধারণ করতে পারে - যা নীচের উদাহরণে দেখানো হয়েছে।
class MyCustomException(Exception):
pass
a=10
b=0
reuslt=None
try:
try:
result=a/b
except ZeroDivisionError as exp:
print("ZeroDivisionError -- ",exp)
raise MyCustomException("Zero Division ") from exp
except MyCustomException as exp:
print("MyException",exp)
print(exp.__cause__)
আউটপুট:
ZeroDivisionError -- division by zero
MyException Zero Division
division by zero
exception(args)
বেশি পছন্দ করেexception (args)
raise exception(args) from None
বলা আছে যে বর্তমানে সক্রিয় ব্যতিক্রমগুলি পরিচালনা করা হয়েছিল এবং তার আর আগ্রহ নেই। অন্যথায় যদি আপনি কোনও except
ব্লকের অভ্যন্তরে একটি ব্যতিক্রম উত্থাপন করেন এবং এটি পরিচালনা না করা হয় তবে উভয় ব্যতিক্রমের জন্য
কিছু সাধারণ ক্ষেত্রে যেখানে আপনাকে কিছু অপ্রত্যাশিত অবস্থার প্রতিক্রিয়া হিসাবে একটি ব্যতিক্রম ছুঁড়ে মারতে হবে এবং আপনি কখনই ধরার ইচ্ছা করেন না, তবে কখনও ঘটতে থাকলে আপনাকে সেখান থেকে ডিবাগ করতে সক্ষম করতে দ্রুত ব্যর্থ হন - সর্বাধিক যৌক্তিক বলে মনে হয় AssertionError
:
if 0 < distance <= RADIUS:
#Do something.
elif RADIUS < distance:
#Do something.
else:
raise AssertionError("Unexpected value of 'distance'!", distance)
ValueError
চেয়ে আরও ভাল কেস AssertionError
কারণ এটির সাথে কোনও সমস্যা নেই (কারণ এখানে কোনওটি তৈরি করা হচ্ছে না) - সমস্যাটি একটি মান সহ। আপনি যদি সত্যিই AssertionError
এই ক্ষেত্রে একটি চান , লিখুন assert distance > 0, 'Distance must be positive'
। তবে আপনাকে সেভাবে ত্রুটি করা উচিত নয় কারণ প্রতিবেদনগুলি বন্ধ করা যেতে পারে ( python -O
)।
-O
।
প্রথমে বিদ্যমান উত্তরগুলি পড়ুন, এটি কেবলমাত্র একটি সংযোজন।
লক্ষ্য করুন আপনি আর্গুমেন্ট সহ বা ছাড়াই ব্যতিক্রম বাড়াতে পারেন।
উদাহরণ:
raise SystemExit
প্রোগ্রামটি প্রস্থান করে তবে কী ঘটেছিল তা আপনি জানতে চাইতে পারেন o সুতরাং আপনি এটি ব্যবহার করতে পারেন।
raise SystemExit("program exited")
এটি প্রোগ্রামটি বন্ধ করার আগে স্টডারারে "প্রোগ্রাম প্রস্থানিত" মুদ্রণ করবে।
raise SystemExit()
ভাল পছন্দ হবে না ? প্রথমটি এমনকি কেন কাজ করে?
একটি ব্যতিক্রম ছোঁড়ার অন্য উপায় হ'ল assert
। কোনও শর্ত পূরণ হচ্ছে কিনা তা যাচাই করার জন্য আপনি দৃ .়তা ব্যবহার করতে পারেন তা না হলে তা উত্থাপিত হবে AssertionError
। আরও তথ্যের জন্য এখানে দেখুন ।
def avg(marks):
assert len(marks) != 0,"List is empty."
return sum(marks)/len(marks)
mark2 = [55,88,78,90,79]
print("Average of mark2:",avg(mark2))
mark1 = []
print("Average of mark1:",avg(mark1))
কেবলমাত্র লক্ষণীয়: এমন সময় আছে যখন আপনি জেনেরিক ব্যতিক্রমগুলি পরিচালনা করতে চান। আপনি যদি একগুচ্ছ ফাইল প্রসেসিং করছেন এবং আপনার ত্রুটিগুলি লগ করছেন তবে আপনি কোনও ফাইলের জন্য ঘটে যাওয়া যে কোনও ত্রুটি ধরতে, লগ ইন করতে এবং বাকী ফাইলগুলি প্রক্রিয়া চালিয়ে যেতে চাইতে পারেন। সেক্ষেত্রে ক
try:
foo()
except Exception as e:
print(str(e)) # Print out handled error
এটি করার একটি ভাল উপায় অবরুদ্ধ করুন। আপনি এখনও raise
সুনির্দিষ্ট ব্যাতিক্রম করতে চাইবেন তবে আপনি কী জানেন তা তারা জানবেন you
আপনার জন্য অজগরটির উত্থাপন বিবরণটি শিখতে হবে। এটি চেষ্টা ব্লকের ভিতরে রাখা উচিত। উদাহরণ -
try:
raise TypeError #remove TypeError by any other error if you want
except TypeError:
print('TypeError raised')
raise
হ'ল স্ট্যাকের ট্রেসটি না ভেঙে কোড প্রয়োগের একাধিক স্তরে কাস্টম ত্রুটি ডিবাগ করতে সক্ষম হওয়ার জন্য আমার দরকার ছিল।