2017-02-20 29 views
0

Приветствует снова StackOverflow сообщество,Поднятие исключения с двумя аргументами

Я читал через библиотеку коллега написал и нашел то, что я не совсем схватывать то, что они пытаются сделать. Но, возможно, это то, чего я не вижу в отношении синтаксиса Python.

class SampleClass: 
    def some_function(self) -> None: 
     try: 
      self.do_something() 
     except CustomException as e: 
      raise DifferentExceptionClass("Could not do something", e) 
      # The previous line is the cause of bewilderment. 

    def do_something(self) -> None: 
     raise CustomException("Tried to do something and failed.") 

Я прочитал, что рейз может принимать аргументы, но это, кажется, поднимает DifferentExceptionClass исключение с кортежем в качестве значения. В чем разница между тем, что сделал мой коллега здесь, и чем-то вроде raise DifferentExeptionClass("Could not do something. {}".format(e)) Есть ли преимущество в том, чтобы сделать исключение своим путем?

Выход для вызова функции в some_function() является:

test = SampleClass() 
test.some_function() 
Traceback (most recent call last): 
    File "<input>", line 4, in some_function 
    File "<input>", line 10, in do_something 
CustomException: Tried to do something and failed. 
During handling of the above exception, another exception occurred: 
Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
    File "<input>", line 6, in some_function 
DifferentExceptionClass: ('Could not do something', CustomException('Tried to do something and failed.',)) 

EDIT: Коллега недостижима для комментариев. Также они давно написали эту библиотеку и не могли вспомнить «настроение», в котором они находились, когда они написали это. Я думал, что он также сделает хороший разговор о СО, если кто-то еще видел подобную реализацию.

+0

Нет, вы просто вызываете конструктор, который принимает два аргумента ... –

ответ

1

Это определенно выгодно для этого. Вы исключаете исключения и предоставляете эту цепочку как информацию пользователю, а не предоставляете самое последнее созданное исключение.

Конечно, ваш коллега мог бы сделать это лучше, используя синтаксис Python для этого. Синтаксис raise exc from raised_exc используется для сгенерирует исключение за другим исключением был поднят:

except CustomException as e: 
    raise DifferentExceptionClass("Could not do something") from e 

и вызывает e (повышенное исключение, CustomException здесь) должны храниться как атрибут самого последнего исключения __cause__ (DifferentExceptionClass здесь) если вам нужно заглянуть в него.

В том случае, когда raise используется внутри except обработчика (как это происходит в вашем фрагменте кода), предыдущее исключение (e) уже неявно хранится как атрибут __context__ для него. Таким образом, передавая его как аргумент, он ничего не делает, кроме как сохраняет исключение в кортеже args.

1

Я читал, что повышение может принимать аргументы, но это, похоже, вызывает исключение DifferentExceptionClass с кортежем в качестве значения.

Exception s также являются классами. На самом деле где-то вы найдете что-то вроде:

class DifferentExceptionClass(Exception): 

    def __init__(self,message,innerException): 
     # ... 
     pass 

Так вы называете конструктор. Как обрабатываются аргументы соответствует исключению. Возможно, что сообщение отформатировано с внутренним исключением, но также возможно, что он делает что-то совершенно другое.

Преимуществом является то, что innerException (или другие параметры) могут быть сохранены, проверены и обработаны соответственно. Если вы форматируете исключение, фактические данные исключения теряются: у вас есть только текстовое представление.