我目前正在研究从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
,我会明确检查。除了这些孤立的情况(发生错误)外,代码还能准确产生我期望的结果。...
我希望我为您提供了所有必要的信息,如果没有,请告诉我。欢迎提供有关如何解决此类问题的任何建议。
答案 0 :(得分:1)
盲目地为字典下标通常会遇到这种问题。您应该切换到在字典上使用get method。它可以很好地处理这种情况:
lists = (jsd.get("data", {}).get("User", {})
.get("stats", {}).get("favouredGenres", []))
这里,我们利用get()
可以采用 default 参数的事实,如果找不到给定的键,它将使用该参数。在前三种情况下,我们提供一个空字典作为默认字典,并在最后一种情况下提供一个空列表(因为这正是我猜想的)。
如果您习惯使用这种访问方法,则可以避免此类问题。
Python Anti-Patterns书lists this是要注意的一本书。在字典中设置值时,推论是setdefault() call。