Класс _mysql_exceptions.DataError: Как проверить тип переменной в условии if - PullRequest
0 голосов
/ 07 января 2020

Мне нужно вернуть результат обновления / вставки из класса базы данных обратно в вызывающий класс, чтобы различить успех и ошибку.
Обновление / вставка возвращает <type long'>, а ошибка базы данных возвращает
<class '_mysql_exceptions.DataError'>.
Поскольку я не уверен насчет возвращаемого типа во время успеха, что это всегда будет длинный тип, я проверяю тип класса.
И я не смог этого сделать. Я попробовал это:

 try:
   x = cursor.execute(q, d)
   conn.commit()
   return x   #Return this to the calling class
 except MySQLdb.Error, e:
   return e   #Return this to the calling class

 if isinstance(e, class): #Doesn't work
 if issubclass(e, _mysql_exceptions): #Doesn't work

Как мне проверить тип e здесь?
Если я все делаю неправильно, пожалуйста, предложите что-нибудь хорошее, спасибо.

1 Ответ

1 голос
/ 07 января 2020

Проблема в том, что isinstance(obj, class) не является допустимым синтаксисом, а _mysql_exceptions является модулем, а не типом исключения, который вызывает TypeError. Чтобы явно проверить тип исключения, вы можете перехватить каждое из них по отдельности:

from _mysql.exceptions import DataError, SomeOtherError, ...
from requests import HTTPError # as an example of a different error

try:
    x = cursor.execute(q, d)
    conn.commit()
except DataError as e:
    # do something
except SomeOtherError as e:
    # do something else
except HTTPError as e:
    # your connection is broken
    # maybe raise from e?

Вам нужно перехватить этот явный тип ошибки, тогда вам не нужно делать if isinstance. Начните без обработки исключений, это приведет вас к исключениям, которые вам нужно необходимо обработать, а все остальное следует считать неожиданным и должно привести к тому, что приложение либо создаст sh, либо распространит какую-либо полезную информацию. сообщение об ошибке, сообщающее, что произошло что-то плохое:

try:
    some_function()
except ValueError as e:
    # this is expected, and is handled accordingly
    handle_expected_error()

# This is optional, normally a bare exception block is considered bad practice,
# but can allow your application to continue functioning while raising some
# helpful error so this isn't suppressed
except Exception as e:
    # this is not expected, I'm going to propagate this error
    # up to be obvious what happened
    handle_unexpected_error()
    #or
    raise from e

Редактировать: Что, если я хочу, чтобы вызывающий класс обрабатывал исключение?

Разумно, и я бы полагался на перехват исключения. Вместо обработки исключения я бы позволил функции просто вызвать исключение и обработать его в вызывающем классе. В качестве очень простого примера:

class MyClass:
    def __init__(self, conn, cursor):
        self.conn = conn
        self.cursor = cursor

    def some_function(self):
        # This raises an error, note I'm not handling it here
        x = self.cursor.execute()
        self.conn.commit()
        return x

    def main_function(self):
        try:
            x = self.some_function()
        except DataError as e:
            handle_exception()
        # unexpected, handle this here
        except Exception as e:
            raise from e
            # or do something else

...