如何避免 KeyError 丢失字典键?
How to avoid KeyError from missing dict keys?
我是 运行 一个在循环中发出 GET 请求的脚本。我测试成功响应,然后将响应转换为 json 对象并执行操作。我的代码如下所示:
response = requests.get(url=url)
if response.status_code == 200:
response_json = response.json()
<do stuff>
else:
<handle error>
有时我会得到一个成功的响应,但无论出于何种原因,dict 会返回一些丢失的数据并且我的脚本从 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,
'conversionType': 'multiply',
'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)
我相信这涵盖了所有基础,但它似乎很笨拙。在这种情况下是否有更好的方法来测试键和有效值的存在,and/or 以保持我的脚本 运行 不中断?
还想知道在每个嵌套条件测试后是否需要 else
语句,或者如果其中一个条件返回 Python 是否默认为底部的 else
False
?
词典同时支持[] operator
和get(k)
方法。如您所知,[] operator
会在找不到键 k 时抛出 KeyError,而 get(k)
只会 return 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 也评论的那样,您还可以提供一个默认的 return 值和键,例如:
print(str.format("d: '{}'", d.get('d', -1))) # d: '-1'
当然,这只有在您可以提供不属于有效 return 值域的默认 return 值时才有用。
您可以使用 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,
'conversionType': 'multiply',
'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")
我是 运行 一个在循环中发出 GET 请求的脚本。我测试成功响应,然后将响应转换为 json 对象并执行操作。我的代码如下所示:
response = requests.get(url=url)
if response.status_code == 200:
response_json = response.json()
<do stuff>
else:
<handle error>
有时我会得到一个成功的响应,但无论出于何种原因,dict 会返回一些丢失的数据并且我的脚本从 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,
'conversionType': 'multiply',
'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)
我相信这涵盖了所有基础,但它似乎很笨拙。在这种情况下是否有更好的方法来测试键和有效值的存在,and/or 以保持我的脚本 运行 不中断?
还想知道在每个嵌套条件测试后是否需要 else
语句,或者如果其中一个条件返回 Python 是否默认为底部的 else
False
?
词典同时支持[] operator
和get(k)
方法。如您所知,[] operator
会在找不到键 k 时抛出 KeyError,而 get(k)
只会 return 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 也评论的那样,您还可以提供一个默认的 return 值和键,例如:
print(str.format("d: '{}'", d.get('d', -1))) # d: '-1'
当然,这只有在您可以提供不属于有效 return 值域的默认 return 值时才有用。
您可以使用 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,
'conversionType': 'multiply',
'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")