所以我說我想運行 3 個函式。他們每個人都可能失敗。我想try-except圍繞它們構建:
- 讓盡可能多的 3 跑 AND
- 如果其中任何一個失敗,則在最后引發錯誤。這可能嗎?
以下代碼因操作 D 失敗(中間失敗),因此永遠無法到達 E:
try:
c = 3 6
print(c)
except TypeError:
raise TypeError("Wrong type provided in operation C")
try:
d = 3 '6'
print(d)
except TypeError:
raise TypeError("Wrong type provided in operation D")
try:
e = 7 5
print(e)
except TypeError:
raise TypeError("Wrong type provided in operation E")
uj5u.com熱心網友回復:
def f1():
print("f1")
def f2():
raise TypeError
print("f2")
def f3():
print("f3")
err = None
for f in [f1, f2, f3]:
try:
f()
except TypeError as e:
# store first error
if not err:
err = e
if err:
raise err
輸出:
f1
f3
[...]
TypeError
如果你的函式有引數,你可以回圈
[(f1, f1_args, f1_kwargs), (f2, f2_args, f2_kwargs), (f3, f3_args, f3_kwargs)]
受到評論的啟發,我試圖想出一個漂亮的背景關系管理器,它在退出時以嵌套的方式引發所有例外。歡迎評論。
class ErrorCollector:
def __init__(self):
self.errors = []
def exec(self, f, suppress_types=None, *args, **kwargs):
suppress_types = tuple(suppress_types) if suppress_types else ()
try:
return f(*args, **kwargs)
except suppress_types as e:
self.errors.append(e)
def _raise_all(self, errors):
if len(errors) == 1:
raise errors[0]
for e in errors:
try:
raise e
except type(e):
self._raise_all(errors[1:])
def __enter__(self):
return self
def __exit__(self, exctype, excinst, exctb):
if excinst is not None:
self.errors.append(excinst)
self._raise_all(self.errors)
def f1():
print('f1')
def f2():
raise TypeError('TypeError in f2')
print('f2')
def f3():
raise ValueError('ValueError in f3')
print('f3')
def f4():
raise TypeError('TypeError in f4')
print('f4')
def f5():
print('f5')
def f6():
raise ZeroDivisionError('ZeroDivisionError in f6')
print('f6')
def f7():
print('f7')
現在您可以使用:
suppress = [TypeError, ValueError]
with ErrorCollector() as ec:
for f in (f1, f2, f3, f4, f5, f6, f7):
ec.exec(f, suppress)
輸出:
f1
f5
[...]
TypeError: TypeError in f2
During handling of the above exception, another exception occurred:
[...]
ValueError: ValueError in f3
During handling of the above exception, another exception occurred:
[...]
TypeError: TypeError in f4
During handling of the above exception, another exception occurred:
[...]
ZeroDivisionError: ZeroDivisionError in f6
請注意,f7沒有執行,因為沒有ZeroDivisionError被抑制。
uj5u.com熱心網友回復:
其他回應提供了各種方式的臨時處理程式。如果這是一個反復出現的需求,一個有趣的替代方法是構建一個類似于 contextlib.suppress 的背景關系管理器,類似于(未經測驗):
class Suppressor:
def __init__(self, *to_suppress):
self.to_suppress = to_suppress # empty = suppress all
self.exceptions = []
def __enter__(self):
pass
def __exit__(self, etype, val, _):
if etype is not None:
# if the exception is selected
if not self.to_suppress or isinstance(val, self.to_suppress):
# store and suppress it
self.exceptions.append(val)
return True
# otherwise ignore
用法:
suppressor = Suppressor(TypeError)
with suppressor:
c = 3 6
print(c) # 9
with suppressor:
d = 3 '6' # error (suppressed)
print(d)
with suppressor:
e = 7 5
print(e) # 12
if suppressor.exceptions:
# TypeError("unsupported operand type(s) for : 'int' and 'str'")
print(repr(suppressor.exceptions[0]))
with suppressor:
# ValueError: invalid literal for int() with base 10: 'a'
e = 7 int('a')
uj5u.com熱心網友回復:
最簡單的是:
errors = 0
try:
c = 3 6
print(c)
except TypeError:
errors =1
try:
d = 3 '6'
print(d)
except TypeError:
errors =1
try:
e = 7 5
print(e)
except TypeError:
errors =1
if errors!=0:
raise TypeError("Wrong type provided in some operation")
如果你想得到哪個操作拋出了 TypeError,你可以將它分配到 3 個不同的變數中。
希望這可以幫助!
uj5u.com熱心網友回復:
您可以收集例外。然后,您實際上可以通過訪問每個例外來重新引發它們,而不是構建一個新的例外。
exceptions = []
try:
raise ValueError("thing 1 error") # simulate error in first function
except ValueError as exc:
exceptions.append(exc)
try:
raise ValueError("thing 2 error") # simulate error in second function
except ValueError as exc:
exceptions.append(exc)
try:
raise ValueError("thing 3 error") # simulate error in third function
except ValueError as exc:
exceptions.append(exc)
然后,您可以選擇引發新的例外。就像是:
if exceptions:
raise Exception("something went wrong")
這使:
Traceback (most recent call last):
File "./main.py", line 21, in <module>
raise Exception("something went wrong")
Exception: something went wrong
或者,您可以直接訪問任何或所有這些例外。就像是:
raise exceptions[1]
這使:
Traceback (most recent call last):
File "./main.py", line 25, in <module>
raise exceptions[1]
File "./main.py", line 11, in <module>
raise ValueError("thing 2 error") # simulate error in second function
ValueError: thing 2 error
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/481342.html
標籤:Python python-3.x 例外
上一篇:java.lang.NumberFormatException:對于輸入字串:“5.3”
下一篇:用更少的行數處理Python例外
