检查类型“NoneType”随机失败

Checking for Type `NoneType` fails in randomly

我目前正在研究从 API 获取一些数据并将其输出到 csv 文件的函数。在这个函数中有一个部分,我在传递数据之前过滤检索到的数据。由于请求 returns 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,我会再次过滤掉一些我不需要的部分,return 是 jsd 的修改版本。

现在的问题是我偶尔会收到错误消息:

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

首先让我感到困惑的是这个错误完全是随机出现的。在一个 运行 中,它在 user_id=7 上不起作用,在下一个中它在 user_id=8475 上不起作用,但在 user_id=7 上工作正常,等等。第二个令人困惑的事情我什至有可能弹出错误,因为我在访问变量之前明确检查它是否属于 NoneType 类型。除了这些发生错误的孤立情况之外,代码产生的结果完全符合我的预期....

希望我已经为您提供了所有必要的东西,如果没有,请告诉我。欢迎就如何解决此类问题提出任何建议。

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

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

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

如果您养成使用这种访​​问方式的习惯,就会避免这些问题。

在字典中设置值时的Python Anti-Patterns book lists this as one to be aware of. The corollary is the setdefault() call