我很难找到“pythonic”方法来做到这一点: 我需要使用相同的 try-except 模式捕获不同的代码块。 要捕获的块彼此不同。 目前,我在代码的几个点重复了相同的 try-except 模式,但有很多例外。
try:
block to catch
except E1, e:
log and do something
except E2, e:
log and do something
...
except Exception, e:
log and do something
有一种很好的方法可以使用 with statement 和上下文管理器装饰器来解决这个问题:
from contextlib import contextmanager
@contextmanager
def error_handler():
try:
yield
except E1, e:
log and do something
...
except Exception, e:
log and do something
...
with error_handler():
block to catch
...
但是,如果我需要知道块中是否有异常会发生什么?即是否可以选择使用 try-except-else 之前的 with block ?
用例示例:
for var in vars:
try:
block to catch
except E1, e:
log and do something
# continue to the next loop iteration
except E2, e:
log and do something
# continue to the next loop iteration
...
except Exception, e:
log and do something
# continue to the next loop iteration
else:
do something else
我可以用pythonic的方式做同样的事情,以避免一次又一次地重复相同的 try-except 模式吗?
答案 0 :(得分:1)
无法找到将无异常信息反馈给调用者的方法。您只能将错误处理放在单独的函数中
def error_handler(exception):
if isinstance(exception, E1):
log and do something
elif isinstance(exception, E2):
...
else:
log and do something
try:
block to catch
except Exception, e:
error_handler(e)
else:
do something else
答案 1 :(得分:1)
我可以看到你已经得到了答案,但是在你已经拥有的东西的基础上,你可以回收一个指示错误状态的对象,并用它来检查你的循环。
在使用这种风格之前,你应该考虑是否隐藏错误处理/记录这种结构是你想要做的事情,因为“Pythonic”通常倾向于明确而不是隐藏细节。
from contextlib import contextmanager
@contextmanager
def error_handler():
error = True
try:
class Internal:
def caughtError(self): return error
yield Internal()
except Exception as e:
print("Logging#1")
except BaseException as e:
print("Logging#2")
else:
error = False
with error_handler() as e:
print("here")
# raise Exception("hopp")
print(e.caughtError()) # True if an error was logged, False otherwise
答案 2 :(得分:0)
从根本上说,你想让你的错误传播,所以不要说:
def foo():
try:
something = xxx
except ValueError as e:
logging.warn("oh noes %s", e)
return 42
except IndexError as e:
logging.warn("on no, not again %s", e)
return 43
go.on(something=something)
这个怎么样:
def foo():
try:
something = xxx
except Exception:
logging.exception("oh noes")
return
go.on(something=something)
然后可能进一步简化:
def foo():
go.on(something=xxx)
让调用者处理错误。
此方法通常称为Crash Early