NoneType не допускает ошибки по подписке только в том случае, если в рамках предложения try / исключением - PullRequest
0 голосов
/ 18 февраля 2019

По какой-то причине, когда я запускаю следующий скрипт, я не получаю никаких TypeError исключений, и мое приложение работает без проблем.(Я использую sqlite3 для базы данных и Flask для самого приложения.)

my_list = []
for dat in data:
    c.execute("""SELECT some_data FROM data_table WHERE date='{}'""".format(dat))
    my_list.append(c.fetchone()[0])
 return my_list

Кажется, что на определенные даты нет никаких данных, поэтому вполне возможно, что там будетслучайный NoneType.Проблема в том, что когда я изменяю свой код на следующий, именно тогда я получаю ошибку NoneType not subscriptable.

my_list = []
for dat in data:
    c.execute("""SELECT some_data FROM data_table WHERE date='{}'""".format(dat))
    try:
        my_list.append(round(c.fetchone()[0]))
    except:
        my_list.append(c.fetchone()[0])
return my_list

Гипотетически, если он сталкивается с объектом NoneType, он будет переходить к except и затем имеют тот же результат, что и исходный блок кода.Вместо этого я получаю эту ошибку, и она ломает мое приложение Flask.Если бы кто-то мог объяснить, что происходит, это было бы здорово!

1 Ответ

0 голосов
/ 18 февраля 2019

c.fetchone() может вернуть None, если больше нет строк для возврата.Если ваш запрос SELECT создает только одну строку, и , если round() вызвало исключение, то повторный вызов c.fetchone() может привести к None, возвращаемому в except обработчик.Проблема здесь заключается в том, что вызов c.fetchone() несколько раз не приведет к тому, что одна и та же первая строка будет возвращена для последующих вызовов.

Вызовите c.fetchone() один раз и проверьте, вернул ли онЗначение, отличное от None, прежде чем что-либо делать с ним:

c.execute("""SELECT some_data FROM data_table WHERE date='{}'""".format(dat))
row = c.fetchone()
if row is not None:
    try:
        my_list.append(round(row[0]))
    except ValueError:  # value that can't be rounded
        continue

Обратите внимание, что почти всегда плохая идея использовать бланк except.Поймайте только ожидаемые исключения, никогда больше ничего.Теперь вы можете легко маскировать ошибки памяти или блокировать прерывания.

Примечание: вы широко открыты для атак SQL-инъекций . не используйте форматирование строки для интерполяции значений, всегда используйте параметры SQL, чтобы драйвер базы данных позаботился о правильном экранировании значений:

c.execute("""SELECT some_data FROM data_table WHERE date=?""", (dat,))

?знак вопроса является заполнителем параметра SQL, а кортеж передает в качестве второго аргумента значения параметра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...