提问人:Vova 提问时间:10/27/2023 最后编辑:mkrieger1Vova 更新时间:11/6/2023 访问量:91
针对多种例外情况的 DRY 方法
A DRY approach for multiple excepts
问:
假设我们有以下代码:
try:
whatever
except ValueError:
something1
except (IndexError, KeyError):
something2
except KeyBoardInterrupt:
something3
except Exception:
something4
else: # no error
something5
finally:
finalize
所以我们有多个例外。我们是否有适合 DRY 方法的其他对立面,因此只有在发生任何错误时才会执行?
例如,我们想设置一些错误变量/标志或记录错误,但除此之外,执行不同的逻辑,而无需编写方法/函数并在每个例外中调用它。except_logic()
答:
0赞
sudden_appearance
10/27/2023
#1
如果您不关心处理订单,您可以执行以下操作:
error_state = True
try:
print("Try") # try raising here to see 'Error occurred'
except ...:
...
else:
print("Else")
error_state = False
finally:
if error_state:
print("Error occurred")
但最好做(更具可读性)
def process_exception(e: Exception):
# if isinstance(e, type1): ... and so on
...
try:
print("Try")
except Exception as e:
...
# do something common
...
process_exception(e)
评论
0赞
Vova
10/27/2023
这实际上就是我所说的.这不是很舒服,我认为除了使用 isinstance 目前最适合 DRY 之外,还要发表评论except_logic()
0赞
blhsing
10/27/2023
#2
更简洁的方法是使用捕获所有异常处理程序来处理具有相同共享逻辑的任何异常,然后在嵌套异常处理程序中为特定于类型的异常处理逻辑重新引发异常:
try:
something()
except Exception as e:
log_exception(e)
try:
raise
except ValueError:
process_valueerror(e)
except (IndexError, KeyError):
process_indexerror_keyerror(e)
# more shared logics can run here after type-specific logics
post_processing(e)
您还可以在注释中使用 @deceze 的解决方案,方法是使用语句显式测试异常的类型:if
try:
something()
except Exception as e:
log_exception(e)
if isinstance(e, ValueError):
process_valueerror(e)
elif isinstance(e, (IndexError, KeyError)):
process_indexerror_keyerror(e)
# more shared logics can run here after type-specific logics
post_processing(e)
这样可以节省 2 行,因为不必重新引发异常,但同时它添加了调用每个附加错误处理程序的样板,因此这取决于您喜欢哪种方法的个人喜好。isinstance(e, ...)
评论
0赞
Vova
11/6/2023
是的,这个,但不是提高 - 使用 isinstance。我会编辑并接受
0赞
Vova
11/6/2023
编辑失败。(只有我能看到)。好吧,编辑更好
0赞
Vova
11/6/2023
try: something() except Exception as e: log_exception(e) if isinstance(e, ValueError): process_valueerror(e) if isinstance(e, (IndexError, KeyError)): process_indexerror_keyerror(e) # more shared logics can run here after type-specific logics post_processing(e)
0赞
blhsing
11/6/2023
在这种情况下,哪一个更好是一个品味问题。您请求的编辑基于评论中提供的解决方案@deceze。我更喜欢我的解决方案,只是因为嵌套块使代码的意图更清晰恕我直言,因为该结构专用于语言的错误处理。当然,您可以使用该方法节省 2 行,但您还必须为每个额外的错误处理程序重复调用的样板,因此我将使用包含这两种解决方案来更新我的答案。try-except
try-except
if..isinstance
isinstance(e, ...)
评论
something
except
isinstance
match