python - সঠিকভাবে ব্যতিক্রম উপেক্ষা কিভাবে




exception exception-handling (8)

সঠিকভাবে ব্যতিক্রম উপেক্ষা কিভাবে?

এই কাজ করার বিভিন্ন উপায় আছে।

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

উদাহরণ নির্দিষ্ট:

পরিবর্তে

try:
    shutil.rmtree(path)
except:
    pass

এটা কর:

shutil.rmtree(path, ignore_errors=True)

এটি একটি shutil.rmtree নির্দিষ্ট। আপনি নিম্নলিখিতটি করে এটিতে সহায়তাটি দেখতে পারেন, এবং আপনি দেখতে পাবেন যে এটি ত্রুটিগুলির কার্যকারিতাও অনুমোদন করতে পারে।

>>> import shutil
>>> help(shutil.rmtree)

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

সাধারণ পদ্ধতির

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

পাইথন নতুন 3.4:

আপনি suppress প্রসঙ্গ suppress আমদানি করতে পারেন:

from contextlib import suppress

কিন্তু শুধুমাত্র সর্বাধিক নির্দিষ্ট ব্যতিক্রম দমন:

with suppress(FileNotFoundError):
    shutil.rmtree(path)

আপনি FileNotFoundError একটি FileNotFoundError উপেক্ষা করবে:

>>> with suppress(FileNotFoundError):
...     shutil.rmtree('bajkjbkdlsjfljsf')
... 
>>> 

docs থেকে:

সম্পূর্ণরূপে ব্যতিক্রমগুলিকে সম্পূর্ণভাবে দমন করে এমন যেকোনো অন্যান্য প্রক্রিয়া হিসাবে, এই প্রসঙ্গ মেনুটি কেবলমাত্র নির্দিষ্ট নির্দিষ্ট ত্রুটিগুলি ঢোকাতে ব্যবহার করা উচিত যেখানে চুপিচুপি প্রোগ্রাম নির্বাহের সাথে চলমান হওয়া সঠিক কাজ বলে পরিচিত।

দ্রষ্টব্য করুন এবং FileNotFoundError শুধুমাত্র Python 3 এ উপলব্ধ।

আপনি যদি Python 2 এ আপনার কোডটি কাজ করতে চান তবে পরবর্তী বিভাগটি দেখুন:

পাইথন 2 এবং 3:

যখন আপনি ব্যতিক্রমটি পরিচালনা না করেই চেষ্টা / ছাড়া করতে চান, কিভাবে আপনি পাইথন এ এটি করবেন?

নিম্নলিখিত সঠিক উপায় অনুসরণ করা হয়?

try :
    shutil.rmtree ( path )
except :
    pass

পাইথন 2 সামঞ্জস্যপূর্ণ কোডের জন্য, কোনও নম্বরে থাকা বিবৃতিটি pass করার সঠিক উপায়। কিন্তু আপনি যখন except BaseException: এটি একই রকম except BaseException: GeneratorExit SystemExit , KeyboardInterrupt SystemExit , এবং SystemExit , এবং সাধারণভাবে, আপনি সেগুলি ধরতে চান না।

আসলে, আপনি ব্যতিক্রম হিসাবে নামকরণ নির্দিষ্ট হিসাবে আপনি হওয়া উচিত।

এখানে পাইথন (2) ব্যতিক্রম অনুক্রমের অংশ , এবং আপনি দেখতে পারেন, যদি আপনি আরো সাধারণ ব্যতিক্রমগুলি ধরেন তবে আপনি যে সমস্যাগুলি প্রত্যাশা করেন তা লুকিয়ে রাখতে পারেন:

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StandardError
      |    +-- BufferError
      |    +-- ArithmeticError
      |    |    +-- FloatingPointError
      |    |    +-- OverflowError
      |    |    +-- ZeroDivisionError
      |    +-- AssertionError
      |    +-- AttributeError
      |    +-- EnvironmentError
      |    |    +-- IOError
      |    |    +-- OSError
      |    |         +-- WindowsError (Windows)
      |    |         +-- VMSError (VMS)
      |    +-- EOFError
... and so on

আপনি সম্ভবত এখানে একটি OSError ধরতে চান, এবং সম্ভবত কোনও ডিরেক্টরি নেই যদি আপনার কোনও ব্যতিক্রম নেই।

আমরা errno লাইব্রেরি থেকে যে নির্দিষ্ট ত্রুটি নম্বর পেতে পারেন, এবং যদি আমরা না যে reraise:

import errno

try:
    shutil.rmtree(path)
except OSError as error:
    if error.errno == errno.ENOENT: # no such file or directory
        pass
    else: # we had an OSError we didn't expect, so reraise it
        raise 

নোট, একটি বেড়া বাড়া মূল ব্যতিক্রম উত্থাপন, যা সম্ভবত আপনি এই ক্ষেত্রে চান। আরো সংক্ষেপে লিখিত, আমরা ব্যতিক্রম ব্যতিক্রম হ্যান্ডলিং কোড সঙ্গে স্পষ্টভাবে pass করতে হবে না:

try:
    shutil.rmtree(path)
except OSError as error:
    if error.errno != errno.ENOENT: # no such file or directory
        raise 

যখন আপনি শুধু একটি চেষ্টা করতে চান-ব্যতিক্রমটি পরিচালনা না করেই, আপনি কিভাবে পাইথন এ এটি করবেন?

নিম্নলিখিত সঠিক উপায় অনুসরণ করা হয়?

try:
    shutil.rmtree(path)
except:
    pass

যখন আপনি ব্যতিক্রমটি পরিচালনা না করেই ধরা চেষ্টা করবেন, তখন আপনি পাইথন এ কীভাবে এটি করবেন?

এটি আপনাকে "পরিচালনা করা" এর অর্থের উপর নির্ভর করে।

আপনি যদি কোনও পদক্ষেপ না নিয়ে এটি ধরতে চান তবে আপনার পোস্ট করা কোডটি কাজ করবে।

আপনি যদি স্ট্যাকের উপরে যাওয়ার ব্যতিক্রমটি বন্ধ না করেই ব্যতিক্রমের জন্য পদক্ষেপ নিতে চান তবে আপনি এটিকে এমন কিছু করতে চান:

try:
    do_something()
except:
    handle_exception()
    raise  #re-raise the exact same exception that was thrown

আমি একাধিক কমান্ড ত্রুটি উপেক্ষা করা এবং fuckit কৌশল ছিল

import fuckit

@fuckit
def helper():
    print('before')
    1/0
    print('after1')
    1/0
    print('after2')

helper()

এটি সাধারণত আপনার জন্য আগ্রহী ত্রুটিগুলি ধরতে সর্বোত্তম অনুশীলন বলে মনে করা হয়। shutil.rmtree ক্ষেত্রে এটি সম্ভবত OSError :

>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
    [...]
OSError: [Errno 2] No such file or directory: '/fake/dir'

যদি আপনি নীরবভাবে সেই ত্রুটিটি উপেক্ষা করতে চান তবে আপনি তা করবেন:

try:
    shutil.rmtree(path)
except OSError:
    pass

কেন? বলুন আপনি (কোনভাবে) ক্রিয়াটির পরিবর্তে ফাংশনটি একটি স্ট্রিংয়ের পরিবর্তে পূর্ণসংখ্যাটি পাস করেছেন, যেমন:

shutil.rmtree(2)

এটি "টাইপ ERROR: ইউনিকোডের সাথে coercing: স্ট্রিং বা বাফারের প্রয়োজন, int পাওয়া যায়" প্রদান করবে - আপনি সম্ভবত এটি উপেক্ষা করতে চান না যা ডিবাগ করা কঠিন হতে পারে।

যদি আপনি স্পষ্টভাবে সমস্ত ত্রুটি উপেক্ষা করতে চান, except: Exception except: ধরা except: বিবৃতি। আবার কেন?

একটি ব্যতিক্রম নির্দিষ্ট করা না প্রতিটি ব্যতিক্রম ক্যাচ, SystemExit ব্যতিক্রম সহ উদাহরণস্বরূপ sys.exit() ব্যবহার করে:

>>> try:
...     sys.exit(1)
... except:
...     pass
... 
>>>

নীচের এই তুলনা করুন, যা সঠিকভাবে প্রস্থান:

>>> try:
...     sys.exit(1)
... except Exception:
...     pass
... 
shell:~$ 

আপনি যদি কখনও ভাল আচরণ কোড লিখতে চান তবে OSError ব্যতিক্রমটি বিভিন্ন ত্রুটির প্রতিনিধিত্ব করতে পারে, তবে উপরের উদাহরণে আমরা কেবল Errno 2 উপেক্ষা করতে চাই, তাই আমরা আরও নির্দিষ্ট হতে পারি:

try:
    shutil.rmtree(path)
except OSError, e:
    if e.errno == 2:
        # suppress "No such file or directory" error
        pass
    else:
        # reraise the exception, as it's an unexpected error
        raise

আপনি import errno করতে if e.errno == errno.ENOENT: মধ্যে if পরিবর্তন করতে if if e.errno == errno.ENOENT:


প্রথম আমি এই থ্রেড থেকে জ্যাক ও'ননারের উত্তরটি উদ্ধৃত করেছি। রেফারেন্স থ্রেড বন্ধ হয়ে গেছে তাই আমি এখানে লিখি:

"পাইথন 3.4 এ আসার এটি একটি নতুন উপায়।

from contextlib import suppress

with suppress(Exception):
    # your code

এখানে যেটি যোগ করেছে তা এখানে রয়েছে: http://hg.python.org/cpython/rev/406b47c64480

এবং এখানে লেখক, রেমন্ড হেটিংয়ের এই সম্পর্কে এবং অন্যান্য পাইথন উষ্ণতার সব ধরণের কথা বলা হয়েছে: https://youtu.be/OSGv2VnC0go?t=43m23s

এই আমার অতিরিক্ত Python 2.7 সমতুল্য:

from contextlib import contextmanager

@contextmanager
def ignored(*exceptions):
    try:
        yield
    except exceptions:
        pass

তারপর আপনি পাইথন 3.4 এ এটি ব্যবহার করেন:

with ignored(Exception):
    # your code

শুধু প্রাসঙ্গিক ব্যতিক্রম বাড়াতে , ঠিক যেমন:

try:
     raise NameError('Joan')
 except NameError:
     print 'An exception just raised again by Joan!'
     raise

এর মত সহজ. :)

আরো বিস্তারিত জানার জন্য, এই ডকুমেন্টেশনটি পড়ুন: https://docs.python.org/3.6/tutorial/errors.html


try:
      doSomething()
except Exception: 
    pass
else:
      stuffDoneIf()
      TryClauseSucceeds()

FYI অন্য কোনও ব্যতিক্রম ব্যতিক্রম ছাড়াই যেতে পারে এবং কেবলমাত্র কোডটি যদি ব্যতিক্রমের কারণ না করে তবেই এটি চালানো হবে।


try:
  doSomething()
except: 
  pass

অথবা

try:
  doSomething()
except Exception: 
  pass

পার্থক্য হল যে প্রথমটি KeyboardInterrupt SystemExit , SystemExit এবং SystemExit মতো জিনিসগুলিকেও SystemExit যা exceptions.BaseException থেকে সরাসরি তৈরি করা হয়েছে। exceptions.BaseException নয়। exceptions.Exception
বিস্তারিত জানার জন্য ডকুমেন্টেশন দেখুন:





try-except