Khi viết mã, tôi thường muốn làm một cái gì đó như thế này:
try:
foo()
except FooError:
handle_foo()
else:
try:
bar()
except BarError:
handle_bar()
else:
try:
baz()
except BazError:
handle_baz()
else:
qux()
finally:
cleanup()
Rõ ràng, điều này là hoàn toàn không thể đọc được. Nhưng nó thể hiện một ý tưởng tương đối đơn giản: thực thi một loạt các hàm (hoặc đoạn mã ngắn), với một trình xử lý ngoại lệ cho mỗi hàm và dừng ngay khi một hàm bị lỗi. Tôi tưởng tượng Python có thể cung cấp đường cú pháp cho mã này, có lẽ giống như thế này:
# NB: This is *not* valid Python
try:
foo()
except FooError:
handle_foo()
# GOTO finally block
else try:
bar()
except BarError:
handle_bar()
# ditto
else try:
baz()
except BazError:
handle_baz()
# ditto
else:
qux()
finally:
cleanup()
Nếu không có ngoại lệ được nêu ra, điều này tương đương với foo();bar();baz();qux();cleanup()
. Nếu ngoại lệ được nêu ra, chúng được xử lý bởi trình xử lý ngoại lệ thích hợp (nếu có) và chúng tôi bỏ qua cleanup()
. Cụ thể, nếu bar()
tăng một FooError
hoặc BazError
, ngoại lệ sẽ không bị bắt và sẽ lan truyền đến người gọi. Điều này là mong muốn vì vậy chúng tôi chỉ nắm bắt các ngoại lệ mà chúng tôi thực sự mong đợi để xử lý.
Bất kể sự xấu xí cú pháp, loại mã này chỉ là một ý tưởng tồi nói chung? Nếu vậy, làm thế nào bạn sẽ cấu trúc lại nó? Tôi tưởng tượng các nhà quản lý bối cảnh có thể được sử dụng để hấp thụ một số sự phức tạp, nhưng tôi không thực sự hiểu nó sẽ hoạt động như thế nào trong trường hợp chung.
handle_*
chức năng?