อะไรคือเหตุผลที่ทำให้การลองยกเว้นอื่นมีอยู่
tryบล็อกช่วยให้คุณสามารถจัดการกับข้อผิดพลาดคาดว่า exceptบล็อกควรจับข้อยกเว้นคุณกำลังเตรียมที่จะจับ หากคุณจัดการกับข้อผิดพลาดที่ไม่คาดคิดรหัสของคุณอาจทำสิ่งที่ผิดและซ่อนข้อบกพร่อง
ส่วนelseคำสั่งจะดำเนินการหากไม่มีข้อผิดพลาดและหากไม่ดำเนินการตามรหัสในtryบล็อกคุณจะหลีกเลี่ยงการจับข้อผิดพลาดที่ไม่คาดคิด อีกครั้งการจับข้อผิดพลาดที่ไม่คาดคิดสามารถซ่อนข้อบกพร่อง
ตัวอย่าง
ตัวอย่างเช่น:
try:
    try_this(whatever)
except SomeException as the_exception:
    handle(the_exception)
else:
    return something
"การพยายามยกเว้น" ห้องสวีทมีสองคำสั่งตัวเลือกและelse ดังนั้นจึงเป็นจริงfinallytry-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 จะดำเนินการไม่ว่าจะเกิดอะไรขึ้นแม้ว่าบรรทัดอื่นจะถูกประเมินด้วยคำสั่ง return
แยกย่อยด้วยรหัสหลอก
มันอาจช่วยในการแยกย่อยนี้ในรูปแบบที่เล็กที่สุดที่แสดงถึงคุณลักษณะทั้งหมดพร้อมความคิดเห็น สมมติว่าสิ่งนี้ถูกต้องทางไวยากรณ์ (แต่ไม่สามารถเรียกใช้ยกเว้นว่ามีการกำหนดชื่อ) รหัสหลอกอยู่ในฟังก์ชั่น
ตัวอย่างเช่น:
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บล็อกให้น้อยที่สุดเพื่อหลีกเลี่ยงการจับข้อยกเว้นที่เราไม่คาดคิดภายใต้หลักการที่ว่าหากโค้ดของเราล้มเหลวเราต้องการให้มันล้มเหลวอย่างดัง นี่คือวิธีที่ดีที่สุด
  ฉันเข้าใจว่าข้อยกเว้นไม่ใช่ข้อผิดพลาด
ใน Python ข้อยกเว้นส่วนใหญ่เป็นข้อผิดพลาด
เราสามารถดูลำดับชั้นข้อยกเว้นโดยใช้ pydoc ตัวอย่างเช่นใน Python 2:
$ python -m pydoc exceptions
หรือ Python 3:
$ python -m pydoc builtins
จะให้ลำดับชั้นกับเรา เราจะเห็นว่าส่วนใหญ่Exceptionเป็นข้อผิดพลาดแม้ว่า Python จะใช้บางอย่างสำหรับสิ่งต่าง ๆ เช่นสิ้นสุดforลูป ( StopIteration) นี่คือลำดับชั้นของ Python 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
ผู้วิจารณ์ถามว่า:
  สมมติว่าคุณมีวิธีที่ส่ง Ping ไปยัง API ภายนอกและคุณต้องการจัดการข้อยกเว้นที่คลาสภายนอก API wrapper คุณเพียงแค่คืนค่า e จากเมธอดภายใต้ข้อยกเว้นที่ e เป็นวัตถุข้อยกเว้น?
ไม่คุณจะไม่ส่งคืนข้อยกเว้นเพียงแค่ทำการเปิดมันด้วยเปลือยraiseเพื่อรักษาสแต็คเทรซ
try:
    try_this(whatever)
except SomeException as the_exception:
    handle(the_exception)
    raise
หรือใน Python 3 คุณสามารถเพิ่มข้อยกเว้นใหม่และรักษา backtrace ด้วยการโยงข้อยกเว้น:
try:
    try_this(whatever)
except SomeException as the_exception:
    handle(the_exception)
    raise DifferentException from the_exception
ผมทำอย่างละเอียดในคำตอบของฉันที่นี่