পাইথনে-বাদে চেষ্টা করে ব্যবহার করা কি ভাল অভ্যাস?


438

পাইথনে সময়ে সময়ে, আমি ব্লকটি দেখতে পাই:

try:
   try_this(whatever)
except SomeException as exception:
   #Handle exception
else:
   return something

চেষ্টা-বাদে অন্যটি থাকার কারণ কী?

আমি এ জাতীয় প্রোগ্রামিং পছন্দ করি না, কারণ এটি প্রবাহ নিয়ন্ত্রণ সম্পাদন করতে ব্যতিক্রম ব্যবহার করে। যাইহোক, যদি এটি ভাষার অন্তর্ভুক্ত থাকে তবে অবশ্যই এটির জন্য ভাল কারণ থাকতে হবে, তাই না?

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

সাধারণত আমি ব্যতিক্রমগুলি হ্যান্ডেল করি:

something = some_default_value
try:
    something = try_this(whatever)
except SomeException as exception:
    #Handle exception
finally:
    return something

বা যদি কোনও ব্যতিক্রম ঘটে তবে আমি সত্যিই কিছু ফিরিয়ে দিতে চাই না, তবে:

try:
    something = try_this(whatever)
    return something
except SomeException as exception:
    #Handle exception

উত্তর:


666

"আমি জানি না যে এটি অজ্ঞতার বাইরে রয়েছে কিনা তবে আমি এই জাতীয় প্রোগ্রামিং পছন্দ করি না, কারণ এটি প্রবাহ নিয়ন্ত্রণ সম্পাদন করতে ব্যতিক্রম ব্যবহার করছে।"

পাইথন বিশ্বে প্রবাহ নিয়ন্ত্রণের ক্ষেত্রে ব্যতিক্রমগুলি ব্যবহার করা সাধারণ এবং সাধারণ।

এমনকি পাইথন কোর বিকাশকারীরা ফ্লো-কন্ট্রোলের জন্য ব্যতিক্রমগুলি ব্যবহার করে এবং সেই স্টাইলটি ভাষাতে খুব বেশি বেক করা হয় (যেমন পুনরায় প্রোটোকল লুপ সমাপ্তির সংকেত দেওয়ার জন্য স্টিপ ইন্টেরেশন ব্যবহার করে )।

তদ্ব্যতীত, চেষ্টা-ব্যতীত শৈলীটি "লুক-বিফোর-ইউ-লিপ" রচনাগুলির মধ্যে অন্তর্নিহিত রেস-কন্ডিশনগুলি রোধ করতে ব্যবহৃত হয় । উদাহরণস্বরূপ, os.path.exes পরীক্ষা করা তথ্যের ফলাফল দেয় যা আপনি এটি ব্যবহারের সময়সীমার পরে পুরানো হতে পারে। একইভাবে, কুই.ফুল পুরানো তথ্যগুলি বাসী হতে পারে returns ব্যবহার করে দেখুন-ছাড়া-অন্য শৈলী এই ক্ষেত্রে অধিক নির্ভরযোগ্য কোড উত্পাদন করা হবে।

"এটি আমার বোঝা যায় যে ব্যতিক্রমগুলি ত্রুটি নয়, সেগুলি কেবল ব্যতিক্রমী অবস্থার জন্য ব্যবহার করা উচিত"

অন্য কয়েকটি ভাষায়, এই নিয়মটি তাদের গ্রন্থাগারে প্রতিবিম্বিত হিসাবে তাদের সাংস্কৃতিক রীতিনীতিগুলি প্রতিফলিত করে। "বিধি" সেই ভাষাগুলির জন্য পারফরম্যান্স বিবেচনার ভিত্তিতে অন্তর্ভুক্ত।

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

অন্য কথায়, আপনার বোঝা যে "ব্যতিক্রমগুলি ব্যতিক্রমী" এটি একটি নিয়ম যা অন্য কয়েকটি ভাষায় বোঝায়, তবে পাইথনের পক্ষে নয়।

"তবে, যদি এটি নিজেই ভাষাতে অন্তর্ভুক্ত হয় তবে অবশ্যই এটির জন্য একটি ভাল কারণ থাকতে হবে, তাই না?"

রেস-কন্ডিশন এড়াতে সহায়তা করার পাশাপাশি, ব্যতিক্রমগুলি লুপগুলির বাইরে ত্রুটি-পরিচালনা করার জন্য খুব কার্যকর। এটি ব্যাখ্যা করা ভাষাগুলিতে একটি প্রয়োজনীয় অপ্টিমাইজেশন যা স্বয়ংক্রিয়ভাবে লুপ ইনগ্রেন্ট কোড গতি ঝোঁক করে না ।

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

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

এছাড়াও, এই স্ট্যাক ওভারফ্লো উত্তরটি দেখুন: ব্যতিক্রমগুলি কি ব্যতিক্রমী ত্রুটির জন্য সত্যই?

"চেষ্টা-বাদে অন্যটি থাকার কারণ কী?"

অন্য-ধারাটি নিজেই আকর্ষণীয়। এটি চলে যখন কোনও ব্যতিক্রম না থাকলে শেষ অবধি-শর্তের আগে। এটিই এর প্রাথমিক উদ্দেশ্য।

অন্য-ধারাটি ব্যতীত, চূড়ান্তকরণের আগে অতিরিক্ত কোড চালানোর একমাত্র বিকল্প হ'ল চেষ্টা-দফায় কোড যুক্ত করার আনাড়ি অনুশীলন। এটি আনাড়ি কারণ এটি কোডে ব্যতিক্রমগুলি ঝুঁকিপূর্ণ করার চেষ্টা করে যা চেষ্টা-ব্লক দ্বারা সুরক্ষিত করার উদ্দেশ্যে নয়।

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

অন্য-দফার জন্য আরেকটি ব্যবহারের ক্ষেত্রে হ'ল এমন ক্রিয়া সম্পাদন করা যা কোনও ব্যতিক্রম না ঘটলে অবশ্যই ঘটে থাকে এবং যখন ব্যতিক্রমগুলি পরিচালনা করা হয় তখন ঘটে না। উদাহরণ স্বরূপ:

recip = float('Inf')
try:
    recip = 1 / f(x)
except ZeroDivisionError:
    logging.info('Infinite result')
else:
    logging.info('Finite result')

আর এক উদাহরণ ইউনিটেস্ট রানারদের মধ্যে ঘটে:

try:
    tests_run += 1
    run_testcase(case)
except Exception:
    tests_failed += 1
    logging.exception('Failing test case: %r', case)
    print('F', end='')
else:
    logging.info('Successful test case: %r', case)
    print('.', end='')

শেষ অবধি, চেষ্টা-ব্লকে অন্য-ধারাটির সর্বাধিক সাধারণ ব্যবহার হ'ল কিছুটা বিউটিফিকেশন (ব্যতিক্রমী ফলাফলগুলি এবং একই ব্যতিক্রমী ফলাফলকে একই মাত্রায় প্রান্তিককরণের জন্য প্রান্তিককরণ) এর জন্য। এই ব্যবহারটি সর্বদা alচ্ছিক এবং কঠোরভাবে প্রয়োজনীয় নয়।


28
"এটি আনাড়ি কারণ এটি কোডে ব্যতিক্রমগুলি ঝুঁকিপূর্ণ করার চেষ্টা করে যা চেষ্টা-ব্লক দ্বারা সুরক্ষিত করার উদ্দেশ্যে নয়" " এটি এখানে সর্বাধিক গুরুত্বপূর্ণ শেখা
ফেলিক্স ডমব্যাক

2
উত্তরের জন্য ধন্যবাদ. পাঠকদের জন্য ব্যবহার-বাদে ব্যবহারের উদাহরণগুলি অনুসন্ধানের জন্য, শুটিলের কপিফিল পদ্ধতিটি দেখুন github.com/python/cpython/blob/master/Lib/shutil.py#L244
সুরিপুরী

2
মুল বক্তব্যটি হ'ল অন্য ক্লজটি কেবল তখনই কার্যকর করা হয় যখন চেষ্টা ক্লজটি সফল হয়।
জোনাথন

172

চেষ্টা-বাদে অন্যটি থাকার কারণ কী?

একটি tryব্লক আপনাকে প্রত্যাশিত ত্রুটিটি পরিচালনা করতে দেয়। exceptব্লক শুধুমাত্র ব্যতিক্রম আপনি পরিচালনা করতে প্রস্তুত করা হয় ধরা উচিত নয়। যদি আপনি কোনও অপ্রত্যাশিত ত্রুটি পরিচালনা করেন তবে আপনার কোডটি ভুল কাজটি করতে পারে এবং বাগগুলি লুকিয়ে রাখতে পারে।

elseকোনও ত্রুটি না থাকলে একটি ধারা কার্যকর করা হবে এবং tryব্লকটিতে সেই কোডটি কার্যকর না করে আপনি একটি অপ্রত্যাশিত ত্রুটি ধরা এড়াবেন। আবার, একটি অপ্রত্যাশিত ত্রুটি ধরা বাগগুলি আড়াল করতে পারে।

উদাহরণ

উদাহরণ স্বরূপ:

try:
    try_this(whatever)
except SomeException as the_exception:
    handle(the_exception)
else:
    return something

"চেষ্টা করুন," বাদে স্যুটটিতে দুটি alচ্ছিক ধারা রয়েছে elseএবং finally। সুতরাং এটি আসলে try-except-else-finally

else যদি কোনও ব্যতিক্রম না থাকে তবেই মূল্যায়ন করবে tryব্লক । এটি আমাদের নীচে আরও জটিল কোডটি সহজ করার অনুমতি দেয়:

no_error = None
try:
    try_this(whatever)
    no_error = True
except SomeException as the_exception:
    handle(the_exception)
if no_error:
    return something

সুতরাং আমরা যদি একটি তুলনা else বিকল্পটির (যা বাগগুলি তৈরি করতে পারে) তবে আমরা দেখতে পাচ্ছি এটি কোডের লাইনকে হ্রাস করে এবং আমাদের আরও বেশি পঠনযোগ্য, রক্ষণাবেক্ষণযোগ্য এবং কম বগি কোড-বেস থাকতে পারে।

finally

finally রিটার্নের স্টেটমেন্টের সাথে অন্য লাইনটি মূল্যায়ন করা হলেও তা নির্ধারণ করবে।

সিউডো-কোড সহ ভেঙে গেছে

এটি সম্ভবত ক্ষুদ্রতম আকারে এটি ভাঙ্গতে সহায়তা করতে পারে যা মন্তব্যগুলির মাধ্যমে সমস্ত বৈশিষ্ট্য প্রদর্শন করে demonst এই সিনট্যাক্টিক্যালি সঠিক হিসাবে ধরে নিন (তবে নামগুলি সংজ্ঞায়িত না করা পর্যন্ত চালানো যায় না) সিউডো-কোড কোনও ফাংশনে রয়েছে।

উদাহরণ স্বরূপ:

try:
    try_this(whatever)
except SomeException as the_exception:
    handle_SomeException(the_exception)
    # Handle a instance of SomeException or a subclass of it.
except Exception as the_exception:
    generic_handle(the_exception)
    # Handle any other exception that inherits from Exception
    # - doesn't include GeneratorExit, KeyboardInterrupt, SystemExit
    # Avoid bare `except:`
else: # there was no exception whatsoever
    return something()
    # if no exception, the "something()" gets evaluated,
    # but the return will not be executed due to the return in the
    # finally block below.
finally:
    # this block will execute no matter what, even if no exception,
    # after "something" is eval'd but before that value is returned
    # but even if there is an exception.
    # a return here will hijack the return functionality. e.g.:
    return True # hijacks the return in the else clause above

এটি সত্য যে আমরা কোডটিতে কোডটি অন্তর্ভুক্ত করতে পারিelse ব্লকে tryব্লকে পরিবর্তে, যদি সেখানে কোন ব্যতিক্রম ছিল যেখানে এটি চালানোর, কিন্তু কি যদি যে কোড নিজেই ধরনের সংক্রামক করছি একটি ব্যতিক্রম উত্থাপন? এটিকে tryব্লকের মধ্যে রেখে দিলে সেই বাগটি লুকিয়ে থাকবে।

আমরা tryআশা করি না এমন ব্যতিক্রমগুলি এড়ানোর জন্য আমরা ব্লকটিতে কোডের লাইনগুলি হ্রাস করতে চাই, এই নীতির অধীনে যে আমাদের কোডটি ব্যর্থ হলে, আমরা এটি জোরে ব্যর্থ হতে চাই। এটি একটি সেরা অনুশীলন

এটি আমার বোঝার ব্যতিক্রমগুলি ত্রুটি নয়

পাইথনে, বেশিরভাগ ব্যতিক্রম ত্রুটি।

পাইডোক ব্যবহার করে আমরা ব্যতিক্রম শ্রেণিবিন্যাস দেখতে পারি। উদাহরণস্বরূপ, পাইথন 2 এ:

$ python -m pydoc exceptions

বা পাইথন 3:

$ python -m pydoc builtins

আমাদের হায়ারার্কি দেবে। আমরা দেখতে পাচ্ছি যে বেশিরভাগ ধরণের Exceptionত্রুটি, যদিও পাইথন এগুলির কয়েকটি forলুপ ( StopIteration) শেষ করার মতো জিনিসের জন্য ব্যবহার করে । এটি পাইথন 3 এর শ্রেণিবিন্যাস:

BaseException
    Exception
        ArithmeticError
            FloatingPointError
            OverflowError
            ZeroDivisionError
        AssertionError
        AttributeError
        BufferError
        EOFError
        ImportError
            ModuleNotFoundError
        LookupError
            IndexError
            KeyError
        MemoryError
        NameError
            UnboundLocalError
        OSError
            BlockingIOError
            ChildProcessError
            ConnectionError
                BrokenPipeError
                ConnectionAbortedError
                ConnectionRefusedError
                ConnectionResetError
            FileExistsError
            FileNotFoundError
            InterruptedError
            IsADirectoryError
            NotADirectoryError
            PermissionError
            ProcessLookupError
            TimeoutError
        ReferenceError
        RuntimeError
            NotImplementedError
            RecursionError
        StopAsyncIteration
        StopIteration
        SyntaxError
            IndentationError
                TabError
        SystemError
        TypeError
        ValueError
            UnicodeError
                UnicodeDecodeError
                UnicodeEncodeError
                UnicodeTranslateError
        Warning
            BytesWarning
            DeprecationWarning
            FutureWarning
            ImportWarning
            PendingDeprecationWarning
            ResourceWarning
            RuntimeWarning
            SyntaxWarning
            UnicodeWarning
            UserWarning
    GeneratorExit
    KeyboardInterrupt
    SystemExit

একজন মন্তব্যকারী জিজ্ঞাসা করলেন:

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

না, আপনি ব্যতিক্রমটি ফিরিয়ে দেবেন না, স্ট্যাকট্রেস raiseসংরক্ষণের জন্য কেবল খালি দিয়ে পুনরায় এটি করুন ।

try:
    try_this(whatever)
except SomeException as the_exception:
    handle(the_exception)
    raise

অথবা, পাইথন 3 এ, আপনি একটি নতুন ব্যতিক্রম বাড়াতে পারেন এবং ব্যতিক্রম চেইন সহ ব্যাকট্রেস সংরক্ষণ করতে পারেন:

try:
    try_this(whatever)
except SomeException as the_exception:
    handle(the_exception)
    raise DifferentException from the_exception

আমি আমার উত্তর এখানে বিস্তারিত ।


upvoted! আপনি সাধারণত হ্যান্ডেল অংশ ভিতরে কি করবেন? আসুন বলুন যে আপনার কাছে এমন একটি পদ্ধতি রয়েছে যা একটি বাহ্যিক এপিআইকে পিং করে এবং আপনি এপিআই র‌্যাপারের বাইরে কোনও ক্লাসে ব্যতিক্রমটি পরিচালনা করতে চান, আপনি কি ব্যতিক্রমী আইনের ব্যতীত অন্য ধারাটির অধীনে পদ্ধতি থেকে ই ফিরে আসবেন?
পাইরেট অ্যাপ

1
@ পাইরেট অ্যাপ আপনাকে ধন্যবাদ! না, এটি ফিরিয়ে দেবেন না, আপনার সম্ভবত একটি খালি raiseবা ব্যতিক্রম শৃঙ্খলা নিয়ে পুনরায় আলোচনা করা উচিত - তবে এটি বিষয়টিতে আরও বেশি এবং এখানে আচ্ছাদিত: stackoverflow.com/q/2052390/541136 - আমি সম্ভবত এই মন্তব্যগুলি সরিয়ে নেওয়ার পরে আপনি তাদের দেখেছেন।
অ্যারন হল

বিস্তারিত জানার জন্য আপনাকে অনেক ধন্যবাদ! এখন পোস্টের মধ্য দিয়ে যাচ্ছেন
পাইরেটঅ্যাপ

36

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

এটি সাধারণত একটি ভাল জিনিস, কারণ এইভাবে কাজ করা কিছু সমস্যা এড়াতে সহায়তা করে (একটি স্পষ্ট উদাহরণ হিসাবে, বর্ণের পরিস্থিতি প্রায়শই এড়ানো হয়), এবং এটি কোডটি আরও কিছুটা পাঠযোগ্য করে তোলে able

আপনার এমন কোনও পরিস্থিতি কল্পনা করুন যেখানে আপনি কিছু ব্যবহারকারীর ইনপুট নেন যা প্রক্রিয়া করা প্রয়োজন, তবে ইতিমধ্যে প্রক্রিয়াজাত একটি ডিফল্ট রয়েছে। try: ... except: ... else: ...গঠন খুব পাঠযোগ্য কোড তোলে:

try:
   raw_value = int(input())
except ValueError:
   value = some_processed_value
else: # no error occured
   value = process_value(raw_value)

এটি অন্যান্য ভাষায় কীভাবে কাজ করতে পারে তার সাথে তুলনা করুন:

raw_value = input()
if valid_number(raw_value):
    value = process_value(int(raw_value))
else:
    value = some_processed_value

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

উদাহরণটি স্বাভাবিকভাবেই কিছুটা স্বল্পতর, তবে এটি দেখায় যে এই কাঠামোর ক্ষেত্রে কিছু ক্ষেত্রে রয়েছে।


15

অজগরটিতে অন্যথায় চেষ্টা বাদ দিয়ে ব্যবহার করা কি ভাল অভ্যাস?

এর উত্তর হ'ল এটি প্রসঙ্গ নির্ভর dependent আপনি যদি এটি করেন:

d = dict()
try:
    item = d['item']
except KeyError:
    item = 'default'

এটি প্রমাণ করে যে আপনি পাইথনকে খুব ভাল জানেন না। এই কার্যকারিতাটি পদ্ধতিতে আবদ্ধ হয় dict.get:

item = d.get('item', 'default')

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

তবে এর অর্থ এই নয় যে আমাদের সমস্ত ব্যতিক্রম হ্যান্ডলিং এড়ানো উচিত। কিছু ক্ষেত্রে এটি জাতির শর্ত এড়াতে পছন্দ করা হয়। কোনও ফাইল উপস্থিত রয়েছে কিনা তা যাচাই করবেন না, কেবল এটি খোলার চেষ্টা করুন এবং উপযুক্ত আইওআরর ধরুন। সরলতা এবং পঠনযোগ্যতার খাতিরে, এটি এপ্যাপসুলেট করার চেষ্টা করুন বা এপ্রোপস হিসাবে এটির ফ্যাক্টর তৈরি করুন।

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


12

নিম্নলিখিত উদাহরণটি দেখুন যা চেষ্টা-ব্যতীত-অবশেষে সম্পর্কে সবকিছু চিত্রিত করে:

for i in range(3):
    try:
        y = 1 / i
    except ZeroDivisionError:
        print(f"\ti = {i}")
        print("\tError report: ZeroDivisionError")
    else:
        print(f"\ti = {i}")
        print(f"\tNo error report and y equals {y}")
    finally:
        print("Try block is run.")

এটি প্রয়োগ করুন এবং এর দ্বারা আসা:

    i = 0
    Error report: ZeroDivisionError
Try block is run.
    i = 1
    No error report and y equals 1.0
Try block is run.
    i = 2
    No error report and y equals 0.5
Try block is run.

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

6

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

In [10]: dict_ = {"a": 1}

In [11]: try:
   ....:     dict_["b"]
   ....: except KeyError:
   ....:     pass
   ....: finally:
   ....:     print "something"
   ....:     
something

যেহেতু প্রত্যেকে অন্য ব্লকটি ব্যবহার করে উল্লেখ করেছে যে আপনার কোডটি আরও পঠনযোগ্য হতে পারে এবং কেবল ব্যতিক্রম হয় যখন ব্যতিক্রম ছুঁড়ে না দেওয়া হয়

In [14]: try:
             dict_["b"]
         except KeyError:
             pass
         else:
             print "something"
   ....:

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

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

4

আপনি যখনই এটি দেখতে পাবেন:

try:
    y = 1 / x
except ZeroDivisionError:
    pass
else:
    return y

বা এমনকি এটি:

try:
    return 1 / x
except ZeroDivisionError:
    return None

পরিবর্তে এটি বিবেচনা করুন:

import contextlib
with contextlib.suppress(ZeroDivisionError):
    return 1 / x

1
এটি আমার প্রশ্নের উত্তর দেয় না, কারণ এটি কেবল আমার বন্ধু ছিল example
জুয়ান আন্তোনিও গোমেজ মরিয়ানো

পাইথনে, ব্যতিক্রমগুলি ত্রুটি নয়। তারা এমনকি ব্যতিক্রমী না। পাইথনে, প্রবাহ নিয়ন্ত্রণের ক্ষেত্রে ব্যতিক্রমগুলি ব্যবহার করা স্বাভাবিক এবং স্বাভাবিক। এটি প্রমাণীকরণের গ্রন্থাগারে কনটেক্সলিব.সপ্রেস () অন্তর্ভুক্তির দ্বারা প্রমাণিত। এখানে রেমন্ড হেটিংজারের উত্তর দেখুন: স্ট্যাকওভারফ্লো.com/a/16138864/1197429 (রেমন্ড মূল পাইথন অবদানকারী, এবং পাইথনিক সব কিছুর উপর কর্তৃত্ব!)
রাজীব বকুলেশ শাহ

4

অন্য কেউ এই মতামত পোস্ট করেনি বলেই আমি বলব

এগুলিতে elseক্লজগুলি এড়িয়ে চলুন try/excepts কারণ তারা বেশিরভাগ মানুষের কাছে অপরিচিত

কিওয়ার্ড ভিন্ন try, exceptএবং finally, এর অর্থelse দফা না স্ব স্পষ্ট-হয়; এটি কম পাঠযোগ্য যেহেতু এটি প্রায়শই ব্যবহৃত হয় না, এটি আপনার কোডটি পড়ে এমন লোকদের ডক্সগুলি ডাবল-চেক করতে চাইবে তা নিশ্চিত হওয়ার জন্য তারা কী ঘটছে তা নিশ্চিত করবে।

(আমি এই উত্তরটি স্পষ্টভাবে লিখছি কারণ আমি একটি পেয়েছি try/except/else আমার কোডবেসে এবং এটি ডাব্লুটিএফের মুহুর্তের কারণ হয়েছিল এবং আমাকে কিছু গুগল করতে বাধ্য করেছিল)।

সুতরাং, যেখানেই আমি ওপি উদাহরণের মতো কোড দেখতে পাচ্ছি:

try:
    try_this(whatever)
except SomeException as the_exception:
    handle(the_exception)
else:
    # do some more processing in non-exception case
    return something

আমি রিফ্যাক্টর করতে পছন্দ করব

try:
    try_this(whatever)
except SomeException as the_exception:
    handle(the_exception)
    return  # <1>
# do some more processing in non-exception case  <2>
return something
  • <1> সুস্পষ্ট প্রত্যাবর্তন, স্পষ্টভাবে দেখায় যে ব্যতিক্রম ক্ষেত্রে, আমরা কাজ শেষ করেছি

  • <2> একটি দুর্দান্ত গৌণ পার্শ্ব-প্রতিক্রিয়া হিসাবে, elseব্লকটিতে যে কোডটি ব্যবহৃত হত তা একটি স্তর দ্বারা উত্সর্গীকৃত হয়।


1
শয়তানের যুক্তি পাল্টা-যুক্তি: যত বেশি লোকেরা এটি ব্যবহার করবে, ততই এটি গ্রহণযোগ্যতর হবে। চিন্তার জন্য কেবল খাদ্য, যদিও আমি সম্মত হই যে পাঠযোগ্যতা আমদানি। এটি বলেছিল, একবার যদি কেউ অন্য চেষ্টাটি বুঝতে পারে, তবে আমি যুক্তি দেব যে এটি অনেক ক্ষেত্রে বিকল্পের চেয়ে অনেক বেশি পঠনযোগ্য।
বব

2

পাইথনের অন্যথায়-অবশেষে অবরুদ্ধ করার চেষ্টা করে কীভাবে বোঝার জন্য এটি আমার সহজ স্নিপেট:

def div(a, b):
    try:
        a/b
    except ZeroDivisionError:
        print("Zero Division Error detected")
    else:
        print("No Zero Division Error")
    finally:
        print("Finally the division of %d/%d is done" % (a, b))

আসুন ডিভ 1/1 চেষ্টা করুন:

div(1, 1)
No Zero Division Error
Finally the division of 1/1 is done

আসুন ডিভ 1/0 চেষ্টা করুন

div(1, 0)
Zero Division Error detected
Finally the division of 1/0 is done

1
আমি মনে করি
এটির

-4

ওপি, আপনি সঠিক। পাইথন বাদে অন্য চেষ্টা করার পরেও এটি কুরুচিপূর্ণ । এটি অন্য ফ্লো-কন্ট্রোল অবজেক্টকে নিয়ে যায় যেখানে কোনওটিরই প্রয়োজন নেই:

try:
    x = blah()
except:
    print "failed at blah()"
else:
    print "just succeeded with blah"

সম্পূর্ণ পরিষ্কার সমতুল্য হ'ল:

try:
    x = blah()
    print "just succeeded with blah"
except:
    print "failed at blah()"

এটি অন্য একটি ধারা থেকে অনেক পরিষ্কার। চেষ্টা করার পরে / বাদে অন্যগুলি প্রায়শই লেখা হয় না, সুতরাং এর কী কী প্রভাব রয়েছে তা চিত্রিত করতে এটি একটি মুহূর্ত সময় নেয়।

আপনি কোনও কাজ করতে পারেন বলে কেবল এর অর্থ এই নয় যে আপনি কোনও কাজ করা উচিত।

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

এখানে আমার 5 সেন্ট। আমাকে পিছনে আসতে হবে এবং কলেজ বিকাশকারীদের মধ্যে যারা 1 ম বছরের দ্বারা লিখিত প্রচুর কোডগুলি সাফ করতে হবে যে তারা স্মার্ট বলে মনে করে এবং কিছু উচ্চতর-আঁটসাঁক, উবার-দক্ষ উপায়ে কোড লিখতে চায় যখন এটি কেবল একটি গোলমাল করে তোলে চেষ্টা এবং পড়তে / পরে সংশোধন করতে। আমি প্রতিদিন এবং দুবার রবিবার পাঠযোগ্যতার পক্ষে ভোট দিই।


15
তুমি ঠিক বলছো. এটি সম্পূর্ণ পরিষ্কার এবং সমতুল্য ... যদি না আপনার printবক্তব্য ব্যর্থ হয়। যদি x = blah()একটি রিটার্ন দেয় তবে কী হবে strআপনার মুদ্রণ বিবৃতিটি print 'just succeeded with blah. x == %d' % x? এখন আপনার TypeErrorএমন একটি উত্পন্ন হয়েছে যেখানে আপনি কোনওটিকে পরিচালনা করার জন্য প্রস্তুত নন; আপনি x = blah()ব্যতিক্রমের উত্সটি সন্ধান করতে যাচ্ছেন এবং এটি সেখানেও নেই। আমি এটি (বা সমতুল্য) একাধিকবার elseকরেছি যেখানে আমাকে এই ভুলটি করা থেকে বিরত রাখত। এখন আমি আরও ভাল জানি। :-D
ডগ আর।

2
... এবং হ্যাঁ, আপনি ঠিক বলেছেন। elseদফা একটি প্রশংসনীয় বিবৃতি নয়, এবং যতক্ষণ না আপনি এটা ব্যবহার করছি, এটা স্বজ্ঞাত নয়। তবে তখনই ছিল না finallyযখন আমি প্রথম এটি ব্যবহার শুরু করেছি ...
ডগ আর

2
ডগ আর echo করার জন্য, এটা নয় কারণ মধ্যে বিবৃতির সময় ব্যতিক্রম সমতুল্য elseদফা হয় না হাতে ক্যাচexcept
অ্যালিস্টায়ার

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

1
@DougR। "আপনি ব্যতিক্রমের উত্সটি সন্ধান করতে পরিদর্শন করছেন x = blah()", tracebackকেন আপনি কোনও ভুল জায়গা থেকে ব্যতিক্রম উত্সটি পরীক্ষা করবেন?
নেহম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.