随机检查类型“ NoneType”失败

时间:2018-12-21 15:39:15

标签: python python-3.x nonetype

我目前正在研究从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 :(得分:1)

盲目地为字典下标通常会遇到这种问题。您应该切换到在字典上使用get method。它可以很好地处理这种情况:

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

这里,我们利用get()可以采用 default 参数的事实,如果找不到给定的键,它将使用该参数。在前三种情况下,我们提供一个空字典作为默认字典,并在最后一种情况下提供一个空列表(因为这正是我猜想的)。

如果您习惯使用这种访​​问方法,则可以避免此类问题。

Python Anti-Patternslists this是要注意的一本书。在字典中设置值时,推论是setdefault() call