อะไรคือเหตุผลที่ทำให้การลองยกเว้นอื่นมีอยู่
try
บล็อกช่วยให้คุณสามารถจัดการกับข้อผิดพลาดคาดว่า except
บล็อกควรจับข้อยกเว้นคุณกำลังเตรียมที่จะจับ หากคุณจัดการกับข้อผิดพลาดที่ไม่คาดคิดรหัสของคุณอาจทำสิ่งที่ผิดและซ่อนข้อบกพร่อง
ส่วนelse
คำสั่งจะดำเนินการหากไม่มีข้อผิดพลาดและหากไม่ดำเนินการตามรหัสในtry
บล็อกคุณจะหลีกเลี่ยงการจับข้อผิดพลาดที่ไม่คาดคิด อีกครั้งการจับข้อผิดพลาดที่ไม่คาดคิดสามารถซ่อนข้อบกพร่อง
ตัวอย่าง
ตัวอย่างเช่น:
try:
try_this(whatever)
except SomeException as the_exception:
handle(the_exception)
else:
return something
"การพยายามยกเว้น" ห้องสวีทมีสองคำสั่งตัวเลือกและ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
จะดำเนินการไม่ว่าจะเกิดอะไรขึ้นแม้ว่าบรรทัดอื่นจะถูกประเมินด้วยคำสั่ง 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
ผมทำอย่างละเอียดในคำตอบของฉันที่นี่