如何避免KeyError缺少字典键?

问题描述

我正在运行一个脚本,该脚本在一个循环中发出GET请求。我测试响应是否成功,然后将响应转换为json对象并执行操作。我的代码如下:

processData

有时我会获得成功的响应,但是无论出于何种原因,字典都会返回一些丢失的数据,并且我的脚本会从response = requests.get(url=url) if response.status_code == 200: response_json = response.json() <do stuff> else: <handle error> 中断。我想进行一次防弹测试,以避免错误并为KeyError检索'high''low'的值。字典的结构为:

response_json['Data']['Data'][1]

我目前在测试中的最佳尝试是:

{'Data': {'Aggregated': False,'Data': [{'close': 0.8062,'conversionType': 'multiply','high': 0.8084,'low': 0.788,'open': 0.8102,'time': 1428465600,'volumefrom': 145.38,'volumeto': 117.2},{'close': 0.8,'high': 0.8101,'low': 0.8,'open': 0.8062,'time': 1428469200,'volumefrom': 262.39,'volumeto': 209.92}],'TimeFrom': 1428465600,'TimeTo': 1428469200},'HasWarning': False,'Message': '','RateLimit': {},'Response': 'Success','Type': 100}

我相信这涵盖了所有基础,但似乎很难。在这种情况下,是否有更好的方法来测试键和有效值的存在,和/或保持脚本运行不中断?

还想知道在每个嵌套的条件测试之后是否需要一个if 'Data' in response_json: if 'Data' in 'Data': if len(response_json['Data']['Data']) > 1: if 'low' and 'high' in response_json['Data']['Data'][1]: if 'low' != None and 'high' != None: <do stuff> else: print("Error:",url) 语句,或者如果其中一个条件返回else,Python是否将默认使用底部的else? / p>

解决方法

字典同时支持[] operatorget(k)方法。如您所知,当找不到键 k 时,[] operator会引发 KeyError ,而get(k)只会返回 None

d = {'a':1,'b': 2,'c':3}
print(str.format("c: '{}'",d.get('c')))    # c: '3'
print(str.format("d: '{}'",d.get('d')))    # d: 'None'

就像@sleepyhead一样,您还可以提供带有键的默认返回值,例如:

print(str.format("d: '{}'",d.get('d',-1))) # d: '-1'

当然,只有在您提供的默认返回值与有效返回值的范围无关时,这才有用。

,

您可以使用try-except块来确保脚本即使在遇到错误时也能继续运行。

例如,您可以像这样构造它:

response = requests.get(url=url)
if response.status_code == 200:
    response_json = response.json()
    try:
        <stuff>
    except KeyError:
        <handle error> #or you can just pass the faulty data
else:
    <handle error>
,

我找不到任何XPath类型的方法来在json中查找键,因此需要堆积的if语句。

您需要修正语法以获取正确的值。

尝试以下代码:

response_json = {'Data': {'Aggregated': False,'Data': [{'close': 0.8062,'conversionType': 'multiply','high': 0.8084,'low': 0.788,'open': 0.8102,'time': 1428465600,'volumefrom': 145.38,'volumeto': 117.2},{'close': 0.8,'high': 0.8101,'low': 0.8,'open': 0.8062,'time': 1428469200,'volumefrom': 262.39,'volumeto': 209.92}],'TimeFrom': 1428465600,'TimeTo': 1428469200},'HasWarning': False,'Message': '','RateLimit': {},'Response': 'Success','Type': 100}


low = high = None  # default values
if 'Data' in response_json.keys():
    if 'Data' in response_json['Data'].keys():
        if len(response_json['Data']['Data']) > 1:
            if 'low' in response_json['Data']['Data'][1]:
               if 'high' in response_json['Data']['Data'][1]:
                  if response_json['Data']['Data'][1]['low'] and response_json['Data']['Data'][1]['high']:
                        low  = response_json['Data']['Data'][1]['low']
                        high = response_json['Data']['Data'][1]['high']

if low and high:   # actually only need to check one                      
   print('<do stuff>','low',response_json['Data']['Data'][1]['low'])
   print('<do stuff>','high',response_json['Data']['Data'][1]['high'])
else:
   print("High\Low not found")

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...