Tôi cần phải giải quyết vấn đề này một vài lần và đưa ra câu hỏi này sau khi tìm kiếm những gì người khác đã làm.
Một tùy chọn - sẽ yêu cầu tái cấu trúc mọi thứ một chút - sẽ là throw
ngoại lệ trong trình tạo (đến một trình xử lý xử lý lỗi khác) thay vì raise
. Dưới đây là những gì có thể trông giống như:
def read(handler):
# the handler argument fixes errors/problems separately
while something():
try:
yield something_else()
except Exception as e:
handler.throw(e)
handler.close()
def err_handler():
# a generator for processing errors
while True:
try:
yield
except Exception1:
handle_exc1()
except Exception2:
handle_exc2()
except Exception3:
handle_exc3()
except Exception:
raise
def process():
handler = err_handler()
for item in read(handler):
do stuff
Điều này không phải lúc nào cũng là giải pháp tốt nhất, nhưng nó chắc chắn là một lựa chọn.
EDIT:
Bạn có thể làm cho nó tất cả chỉ là một chút đẹp hơn với trang trí theo cách này (tôi đã không kiểm tra này, nhưng nó cũng làm việc, EDIT: không làm việc, tôi sẽ sửa chữa nó sau này, nhưng ý tưởng là âm thanh):
def handled(handler):
"""
A decorator that applies error handling to a generator.
The handler argument received errors to be handled.
Example usage:
@handled(err_handler())
def gen_function():
yield the_things()
"""
def handled_inner(gen_f):
def wrapper(*args, **kwargs):
g = gen_f(*args, **kwargs)
while True:
try:
yield from g
except Exception as e:
handler.throw(e)
return wrapper
return handled_inner
@handled(err_handler())
def read():
while something():
yield something_else()
def process():
for item in read():
do stuff
Nguồn
2017-08-04 02:27:57
Cảm ơn! Sự trình diện này là một trường hợp. Bạn có thể xem câu hỏi tiếp theo: http://stackoverflow.com/q/11366892/989121? – georg