Правильный способ объявить пользовательские исключения в современном Python?

Вы можете ответить на этот и подобные вопросы с помощью windbg, sos и !gcroot

0:008> !gcroot -nostacks 0000000002354160
DOMAIN(00000000002FE6A0):HANDLE(Strong):241320:Root:00000000023541a8(System.Thre
ading._TimerCallback)->
00000000023540c8(System.Threading.TimerCallback)->
0000000002354050(System.Timers.Timer)->
0000000002354160(System.Threading.Timer)
0:008>

. В обоих случаях встроенный таймер должен предотвратить GC объекта обратного вызова (через GCHandle). Разница в том, что в случае System.Timers.Timer обратный вызов ссылается на объект System.Timers.Timer (который реализован внутренне с помощью System.Threading.Timer)

1108
задан Marco 21 January 2019 в 14:50
поделиться

3 ответа

Возможно, я пропустил вопрос, но почему бы и нет:

class MyException(Exception):
    pass

Изменить: , чтобы что-то переопределить (или передать дополнительные аргументы), сделайте следующее:

class ValidationError(Exception):
    def __init__(self, message, errors):

        # Call the base class constructor with the parameters it needs
        super(ValidationError, self).__init__(message)

        # Now for your custom code...
        self.errors = errors

Таким образом, вы можете передать dict сообщений об ошибках для второго параметра, а затем вернуться к нему с помощью e.errors


Обновление Python 3: В Python 3+ вы можете использовать это немного более компактное использование super () :

class ValidationError(Exception):
    def __init__(self, message, errors):

        # Call the base class constructor with the parameters it needs
        super().__init__(message)

        # Now for your custom code...
        self.errors = errors
1217
ответ дан 19 December 2019 в 20:14
поделиться

Вы должны переопределить __ repr __ или __ unicode __ вместо использования message, аргументы, которые вы предоставляете при создании исключения, будут в атрибуте args объекта исключения.

17
ответ дан 19 December 2019 в 20:14
поделиться

Нет, «сообщение» не запрещено. Это просто устарело. Ваше приложение будет нормально работать с использованием сообщения. Но, конечно, вы можете захотеть избавиться от ошибки устаревания.

Когда вы создаете собственные классы исключений для своего приложения, многие из них являются подклассами не только от Exception, но и от других, например ValueError или подобных. Затем вам нужно адаптироваться к их использованию переменных.

И если у вас много исключений в вашем приложении, обычно неплохо иметь общий настраиваемый базовый класс для всех из них, чтобы пользователи ваших модулей могли делать

try:
    ...
except NelsonsExceptions:
    ...

] И в этом случае вы можете выполнить там необходимые __ init__ и __str __ , поэтому вам не придется повторять это для каждого исключения. Но просто вызов переменной сообщения чем-то еще, кроме message, дает трюк.

В любом случае, вам нужны только __ init__ или __str __ , если вы делаете что-то отличное от того, что делает само Exception. И потому, что если устаревание, то вам понадобятся оба, иначе вы получите ошибку. Это не так уж много дополнительного кода, необходимого для каждого класса. ;)

7
ответ дан 19 December 2019 в 20:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: