Предложение replace*SpecificException as exc соответствует конкретному исключению независимо от того, насколько глубоко оно встроено. в группах исключений. Пока все хорошо.
Переменная exc наверняка является ExceptionGroup (может быть, BasicExceptionGroup, но в моем случае это не имеет значения). . Свойство exc.Exceptions может содержать SpecificException, но оно также может содержать только другую ExceptionGroup (с другой ExceptionGroup внутри) и где-то глубоко внизу, где это может быть SpecificException. .
Каков способ Pythonic извлечь это встроенное SpecificException из дерева ExceptionGroup?
Я создал этот пример, который демонстрирует проблему и представляет мою текущую ситуацию. решение (что неприятно).
Код: Выделить всё
from typing import Iterator, Type
import trio
class AlphaExc(Exception):
alphaAttr: str
def __init__(self, message: str, alphaAttr: str):
super().__init__(message)
self.alphaAttr = alphaAttr
class BetaExc(Exception):
pass
async def alpha():
raise AlphaExc("Alpha exception", "foo")
async def beta():
raise BetaExc("Beta exception")
# My helper function to extract exceptions from exception group. Is it possible to do it in a more elegant way?
def extractException[T](excGroup: BaseExceptionGroup, excType: Type[T]) -> Iterator[T]:
for exc in excGroup.exceptions:
if isinstance(exc, BaseExceptionGroup):
yield from extractException(exc, excType)
else:
if isinstance(exc, excType):
yield exc
async def main():
try:
try:
async with trio.open_nursery() as nursery:
nursery.start_soon(alpha)
nursery.start_soon(beta)
except* (AlphaExc, BetaExc) as exc:
match, rest = exc.split(AlphaExc) # This is here just to demonstrate embedded exception group
raise BaseExceptionGroup("My group exception", [match, rest])
except* AlphaExc as excgroup:
for ex in extractException(excgroup, AlphaExc):
print(f"Alpha exception ({type(ex)}): {ex} - {ex.alphaAttr}")
if __name__ == '__main__':
trio.run(main)
Интересно, действительно ли это лучший способ работы с исключениями со времен Python 3.11 — скопировать функцию exctractException из приведенного выше примера в каждый проект и использовать этот шаблонный код
Код: Выделить всё
except SpecificException as excgroup:
for exc in extractException(excgroup, SpecificException):
# work with exc
Код: Выделить всё
except SpecificException as exc:
# work with exc
Примечание: я нашел аналогичный вопрос здесь, в SO, но ответы (включая принятую) не учитывается во встроенных группах.
Подробнее здесь: https://stackoverflow.com/questions/792 ... group-tree
Мобильная версия