如何减少到一次尝试,除了声明
How to reduce to just one try,except statements
我有一个包含多个 try-except 语句的字典。
我尝试使用 r.get() 检索值,但它向我抛出一个类型错误 NoneObject。我知道 .get() 的默认参数是 None,但它不起作用。我有多个列表,我在每个迭代中附加来自不同字典值的数据。
如何将代码缩减为单个 try-except 语句?谢谢!
这是我的代码:
for num in issue_number:
print(num)
Response = requests.get(f'https://example.com/rest/api/2/issue/Proj-{num}?expand=changelog&maxResults =1000', auth=(example))
r = Response.json()
try:
task_list.append(r['key'])
except TypeError:
task_list.append('NA')
try:
summary_list.append(r['fields']['summary'])
except TypeError:
summary_list.append('NA')
try:
assignee_list.append(r['fields']['assignee']['displayName'])
except TypeError:
assignee_list.append('NA')
try:
created_list.append(r['fields']['created'])
except:
created_list.append('NA')
try:
status_list.append(r['fields']['status']['name'])
except:
status_list.append('NA')
try:
due_date_list.append(r['fields']['duedate'])
except:
due_date_list.append('NA')
try:
resolution_list.append(r['fields']['resolution']['name'])
except:
resolution_list.append('NA')
try:
resolution_date_list.append(r['fields']['resolutiondate'])
except:
resolution_date_list.append('NA')
您可以通过链接多个 get
调用来避免所有这些情况:
for num in issue_number:
print(num)
Response = requests.get(f'https://example.com/rest/api/2/issue/Proj-{num}?expand=changelog&maxResults =1000', auth=(example))
r = Response.json()
task_list.append(r.get('key', 'NA'))
summary_list.append(r.get('fields', {}).get('summary', 'NA'))
assignee_list.append(r.get('fields', {}).get('assignee', {}).get('displayName','NA'))
created_list.append(r.get('fields', {}).get('created', 'NA'))
status_list.append(r.get('fields', {}).get('status', {}).get('name', 'NA'))
due_date_list.append(r.get('fields', {}).get('duedate', 'NA'))
resolution_list.append(r.get('fields', {}).get('resolution', {}).get('name', 'NA'))
resolution_date_list.append(r.get('fields', {}).get('resolutiondate', 'NA'))
但是,由于您多次执行相同的操作,您可能会发现使用函数更方便,例如:
def get_deep(d, *keys, default=None):
for k in keys:
if not d or k not in d:
# Stop early if a key is not found
return default
d = d[k]
return d if d is not None else default
# ...
for num in issue_number:
print(num)
Response = requests.get(f'https://example.com/rest/api/2/issue/Proj-{num}?expand=changelog&maxResults =1000', auth=(example))
r = Response.json()
task_list.append(get_deep(r, 'key', default='NA'))
summary_list.append(get_deep(r, 'fields', 'summary', default='NA'))
assignee_list.append(get_deep(r, 'fields', 'assignee', 'displayName', default='NA'))
created_list.append(get_deep(r, 'fields', 'created', default='NA'))
status_list.append(get_deep(r, 'fields', 'status', 'name', default='NA'))
due_date_list.append(get_deep(r, 'fields', 'duedate', default='NA'))
resolution_list.append(get_deep(r, 'fields', 'resolution', 'name', default='NA'))
resolution_date_list.append(get_deep(r, 'fields', 'resolutiondate', default='NA'))
您可以将密钥作为元组存储在某个列表中,然后检查这些密钥对是否存在于 r
中,如果存在,将它们添加到您的 status_list
.
necessary_keys = [('key'), ('fields', 'summary'), ('fields', 'assignee', 'displayName'),
('fields', 'created'), ('fields', 'status', 'name'),
('fields', 'duedate'), ('fields', 'resolution', 'name'),
('fields', 'resolutiondate')]
def check_keys(dict_, keys):
if keys[0] in dict_:
if len(keys) == 1:
return dict_[keys[0]]
else:
return check_keys(dict_[keys[0]], keys[1:])
return 'NA'
issue_number = [0]
status_list = []
for num in issue_number:
print(num)
#Response = requests.get(f'https://example.com/rest/api/2/issue/Proj-{num}?expand=changelog&maxResults =1000', auth=(example))
#r = Response.json()
r = {'fields': {'summary': 'test1', 'status': {'name': 'test2'}}}
for key in necessary_keys:
status_list.append(check_keys(r, key))
print(status_list)
输出:
['NA', 'test1', 'NA', 'NA', 'test2', 'NA', 'NA', 'NA']
我倾向于将这类代码重构为:
from collections import namedtuple
Issue = namedtuple('Issue', [
'task_key', 'summary', 'assignee', 'created'
])
import logging
logger = logging.getLogger(__name__)
def get_issue(num):
res = requests.get(f'https://example.com/rest/api/2/issue/Proj-{num}?expand=changelog&maxResults=1000', auth=(example))
res.raise_for_status()
r = res.json()
return Issue(
r['key'], r['fields']['summary'],
r['fields']['assignee']['displayName'],
r['fields']['created'],
)
issues = {}
for num in issue_number:
try:
issues[num] = get_issue(num)
except:
logger.exception("unable to process issue %s", num)
如果你真的想获得部分条目,那么使用来自@jdehesa 的 get_deep
可能会有用
您可以使用字典来避免可变数量的变量。此外,您可以使用 functools.reduce
来迭代嵌套字典。这是一个完整的例子:
from collections import defaultdict
from functools import reduce
from operator import getitem
def getitem_from_dict(dataDict, mapList):
"""Iterate nested dictionary"""
return reduce(getitem, mapList, dataDict)
d = {1: {'key': 'key1', 'fields': {'summary': 'summary1'}},
2: {'key': 'key2', 'fields': {'summary': 'summary2'}},
3: {'key': 'key3', 'fields': {'summary': 'summary3'}}}
res = defaultdict(list)
lsts = ['task', 'summary']
keys = [['key'], ['fields', 'summary']]
for num in [1, 2, 3]:
r = d[num]
for lst, key in zip(lsts, keys):
try:
res[lst].append(getitem_from_dict(r, key))
except TypeError:
res[lst].append('NA')
print(res['task'])
# ['key1', 'key2', 'key3']
print(res['summary'])
# ['summary1', 'summary2', 'summary3']
我有一个包含多个 try-except 语句的字典。 我尝试使用 r.get() 检索值,但它向我抛出一个类型错误 NoneObject。我知道 .get() 的默认参数是 None,但它不起作用。我有多个列表,我在每个迭代中附加来自不同字典值的数据。
如何将代码缩减为单个 try-except 语句?谢谢!
这是我的代码:
for num in issue_number:
print(num)
Response = requests.get(f'https://example.com/rest/api/2/issue/Proj-{num}?expand=changelog&maxResults =1000', auth=(example))
r = Response.json()
try:
task_list.append(r['key'])
except TypeError:
task_list.append('NA')
try:
summary_list.append(r['fields']['summary'])
except TypeError:
summary_list.append('NA')
try:
assignee_list.append(r['fields']['assignee']['displayName'])
except TypeError:
assignee_list.append('NA')
try:
created_list.append(r['fields']['created'])
except:
created_list.append('NA')
try:
status_list.append(r['fields']['status']['name'])
except:
status_list.append('NA')
try:
due_date_list.append(r['fields']['duedate'])
except:
due_date_list.append('NA')
try:
resolution_list.append(r['fields']['resolution']['name'])
except:
resolution_list.append('NA')
try:
resolution_date_list.append(r['fields']['resolutiondate'])
except:
resolution_date_list.append('NA')
您可以通过链接多个 get
调用来避免所有这些情况:
for num in issue_number:
print(num)
Response = requests.get(f'https://example.com/rest/api/2/issue/Proj-{num}?expand=changelog&maxResults =1000', auth=(example))
r = Response.json()
task_list.append(r.get('key', 'NA'))
summary_list.append(r.get('fields', {}).get('summary', 'NA'))
assignee_list.append(r.get('fields', {}).get('assignee', {}).get('displayName','NA'))
created_list.append(r.get('fields', {}).get('created', 'NA'))
status_list.append(r.get('fields', {}).get('status', {}).get('name', 'NA'))
due_date_list.append(r.get('fields', {}).get('duedate', 'NA'))
resolution_list.append(r.get('fields', {}).get('resolution', {}).get('name', 'NA'))
resolution_date_list.append(r.get('fields', {}).get('resolutiondate', 'NA'))
但是,由于您多次执行相同的操作,您可能会发现使用函数更方便,例如:
def get_deep(d, *keys, default=None):
for k in keys:
if not d or k not in d:
# Stop early if a key is not found
return default
d = d[k]
return d if d is not None else default
# ...
for num in issue_number:
print(num)
Response = requests.get(f'https://example.com/rest/api/2/issue/Proj-{num}?expand=changelog&maxResults =1000', auth=(example))
r = Response.json()
task_list.append(get_deep(r, 'key', default='NA'))
summary_list.append(get_deep(r, 'fields', 'summary', default='NA'))
assignee_list.append(get_deep(r, 'fields', 'assignee', 'displayName', default='NA'))
created_list.append(get_deep(r, 'fields', 'created', default='NA'))
status_list.append(get_deep(r, 'fields', 'status', 'name', default='NA'))
due_date_list.append(get_deep(r, 'fields', 'duedate', default='NA'))
resolution_list.append(get_deep(r, 'fields', 'resolution', 'name', default='NA'))
resolution_date_list.append(get_deep(r, 'fields', 'resolutiondate', default='NA'))
您可以将密钥作为元组存储在某个列表中,然后检查这些密钥对是否存在于 r
中,如果存在,将它们添加到您的 status_list
.
necessary_keys = [('key'), ('fields', 'summary'), ('fields', 'assignee', 'displayName'),
('fields', 'created'), ('fields', 'status', 'name'),
('fields', 'duedate'), ('fields', 'resolution', 'name'),
('fields', 'resolutiondate')]
def check_keys(dict_, keys):
if keys[0] in dict_:
if len(keys) == 1:
return dict_[keys[0]]
else:
return check_keys(dict_[keys[0]], keys[1:])
return 'NA'
issue_number = [0]
status_list = []
for num in issue_number:
print(num)
#Response = requests.get(f'https://example.com/rest/api/2/issue/Proj-{num}?expand=changelog&maxResults =1000', auth=(example))
#r = Response.json()
r = {'fields': {'summary': 'test1', 'status': {'name': 'test2'}}}
for key in necessary_keys:
status_list.append(check_keys(r, key))
print(status_list)
输出:
['NA', 'test1', 'NA', 'NA', 'test2', 'NA', 'NA', 'NA']
我倾向于将这类代码重构为:
from collections import namedtuple
Issue = namedtuple('Issue', [
'task_key', 'summary', 'assignee', 'created'
])
import logging
logger = logging.getLogger(__name__)
def get_issue(num):
res = requests.get(f'https://example.com/rest/api/2/issue/Proj-{num}?expand=changelog&maxResults=1000', auth=(example))
res.raise_for_status()
r = res.json()
return Issue(
r['key'], r['fields']['summary'],
r['fields']['assignee']['displayName'],
r['fields']['created'],
)
issues = {}
for num in issue_number:
try:
issues[num] = get_issue(num)
except:
logger.exception("unable to process issue %s", num)
如果你真的想获得部分条目,那么使用来自@jdehesa 的 get_deep
可能会有用
您可以使用字典来避免可变数量的变量。此外,您可以使用 functools.reduce
来迭代嵌套字典。这是一个完整的例子:
from collections import defaultdict
from functools import reduce
from operator import getitem
def getitem_from_dict(dataDict, mapList):
"""Iterate nested dictionary"""
return reduce(getitem, mapList, dataDict)
d = {1: {'key': 'key1', 'fields': {'summary': 'summary1'}},
2: {'key': 'key2', 'fields': {'summary': 'summary2'}},
3: {'key': 'key3', 'fields': {'summary': 'summary3'}}}
res = defaultdict(list)
lsts = ['task', 'summary']
keys = [['key'], ['fields', 'summary']]
for num in [1, 2, 3]:
r = d[num]
for lst, key in zip(lsts, keys):
try:
res[lst].append(getitem_from_dict(r, key))
except TypeError:
res[lst].append('NA')
print(res['task'])
# ['key1', 'key2', 'key3']
print(res['summary'])
# ['summary1', 'summary2', 'summary3']