Проверка на тип `NoneType` не проходит случайно - PullRequest
0 голосов
/ 21 декабря 2018

В настоящее время я работаю над функцией, которая получает некоторые данные из API и выводит их в CSV-файл.В этой функции есть часть, где я фильтрую полученные данные перед их передачей.Поскольку существует вероятность того, что запрос вернет None, я решил явно проверить это и реализовать специальное поведение в этом случае.Пожалуйста, взгляните на следующий фрагмент кода.

r = requests.post(self.settings['apiurl'],
                  headers=self.settings['header'],
                  json={'query': query_string, 'variables': vars})

jsd = json.loads(r.text)
if jsd is not None:
    lists = jsd["data"]["User"]["stats"]["favouredGenres"]
    newlist = [entry for entry in lists if entry["meanScore"] is not None]
    if not newlist:
        return None
    else:
        jsd["data"]["User"]["stats"]["favouredGenres"] = newlist
        try:
            jsd = jsd  # json.loads(jsd)
        except ValueError:
            return None
        else:
            return jsd
else:
    return None

Часть if jsd is not None является вышеупомянутой проверкой.Если jsd не None, я снова отфильтрую некоторые ненужные части и верну измененную версию jsd.

Проблема сейчас в том, что я время от времени получаю сообщение об ошибке:

    lists = jsd["data"]["User"]["stats"]["favouredGenres"]
TypeError: 'NoneType' object is not subscriptable

Первое, что меня действительно смущает, это то, что эта ошибка появляется совершенно случайно.В одном прогоне он не работает на user_id=7, в следующем он не работает на user_id=8475, но отлично работает на user_id=7 и т. Д. Второе, что меня смущает, это то, что это возможно даже при ошибкевсплывающее окно, так как я явно проверяю перед доступом к переменной, имеет ли она тип NoneType.Помимо этих единичных случаев, когда происходит ошибка, код дает именно те результаты, которые я ожидаю ...

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

1 Ответ

0 голосов
/ 21 декабря 2018

Слепое написание сценария в словаре обычно сопряжено с такой проблемой.Вы должны перейти на использование get метода в словарях.Он вполне может справиться с этим случаем:

lists = (jsd.get("data", {}).get("User", {})
         .get("stats", {}).get("favouredGenres", []))

Здесь мы используем тот факт, что get() может принимать аргумент по умолчанию , который он будет использовать, если данный ключ не найден,В первых 3 случаях мы предоставляем пустой словарь по умолчанию, и мы предоставляем пустой список для последнего случая (так как я предполагаю, что вы ожидаете).

Если вы попадаете вПри использовании этого метода доступа вы избежите подобных проблем.

Python Anti-Patterns book перечисляет этот как один, о котором следует знать.Следствием является вызов setdefault () при установке значений в словаре.

...