Есть ли разница между «поднять исключение ()» и «поднять исключение» без скобок?


100

Определение исключения без параметров:

class MyException(Exception):
    pass

При поднятии есть ли разница между:

raise MyException

и

raise MyException()

Я не мог найти ничего; это просто перегруженный синтаксис?


1
Прочтите этот ответ: stackoverflow.com/questions/13052991/…
satoru

1
Строго говоря, это не синтаксис. Python не может знать, получит ли он класс или экземпляр до времени выполнения.
asmeurer

Ответы:


116

Короткий ответ заключается в том, что оба они делают одно raise MyExceptionи raise MyException()то же. Эта первая форма автоматически создает ваше исключение.

В соответствующем разделе документации говорится: « raise оценивает первое выражение как объект исключения. Оно должно быть либо подклассом, либо экземпляром BaseException. Если это класс, экземпляр исключения будет получен при необходимости путем создания экземпляра класса с помощью без аргументов ".

Тем не менее, несмотря на то, что семантика одинакова, первая форма микроскопически быстрее, а вторая форма более гибкая (потому что вы можете передавать ей аргументы, если это необходимо).

Обычный стиль, который большинство людей использует в Python (т. Е. В стандартной библиотеке, в популярных приложениях и во многих книгах), - это использование raise MyExceptionпри отсутствии аргументов. Люди создают экземпляр исключения только тогда, когда нужно передать некоторые аргументы. Например: raise KeyError(badkey).


18
Почему первая форма (без скобок) будет микроскопически быстрее?
jamesdlin

15
@jamesdlin Потому что код C для автоматического создания экземпляра не имеет интерпретируемых накладных расходов, которые возникают из-за того, что вы сами выполняете вызов.
Раймонд Хеттингер,

4

Посмотрите документы для raiseутверждения . Он создает экземпляр MyException.


1
Стоит отметить, что синтаксис forraise немного изменился в Python 3. Часть, имеющая отношение к этому вопросу, остается той же (по- raise ExceptionTypeпрежнему создается экземпляр типа, вызывая его конструктор без аргументов).
Blckknght

0

Да, есть разница между ValueErrorиValueError()

ValueErrorявляется классом, тогда как ValueError()создает экземпляр класса. Это причина того, что type(ValueError) is typeиtype(ValueError()) is ValueError

Единственная цель raise- вызвать исключение,

когда мы используем ValueError, будет вызываться класс, который, в свою очередь, запускает конструктор ValueError()

когда мы используем ValueError(), метод ValueError()вызывается напрямую.

Примечание: raise ValueError # shorthand for 'raise ValueError()'

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.