You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单个循环中逐一校验API返回字典的多个key,缺失时自动赋值为None

解决方案

核心思路是封装通用嵌套结构安全取值函数,一次性覆盖所有字典缺key、列表超界、中间值为空的异常场景,无需为每个字段单独写判断分支或异常捕获,各字段取值逻辑完全独立互不干扰。


步骤1:定义安全取值工具函数

def safe_get(root, *path, default=None):
    """
    从嵌套字典/列表结构中安全取值,取值失败自动返回默认值
    :param root: 取值根对象
    :param path: 取值路径,支持字符串(字典key)、整数(列表索引)混合传入
    :param default: 取值失败返回的默认值,默认为None
    """
    current = root
    for item in path:
        try:
            current = current[item]
        except (KeyError, IndexError, TypeError):
            # 分别覆盖字典无对应key、列表索引超界、当前值为非可索引类型的异常
            return default
    return current

步骤2:重构业务代码

使用safe_get函数重构所有字段取值逻辑,每个字段仅需一行即可实现缺失自动设为None,同时增加接口返回兜底处理避免结构异常报错:

import requests
import collections
from django.conf import settings
# 此处导入你自己的BookFilterForm、render等依赖

def safe_get(root, *path, default=None):
    current = root
    for item in path:
        try:
            current = current[item]
        except (KeyError, IndexError, TypeError):
            return default
    return current

def your_view_func(request):
    book_import = []

    if request.method == 'POST':
        filter_ch = BookFilterForm(request.POST)
        if filter_ch.is_valid():
            cd = filter_ch.cleaned_data

            filter_choice = cd['choose_v']
            filter_search = cd['search']

            search_url = "https://www.googleapis.com/books/v1/volumes?"

            params = {
                'q': f"{filter_choice}{filter_search}",
                'key': settings.BOOK_DATA_API_KEY,
                'maxResults': 2,
                'printType': 'books'
            }

            r = requests.get(search_url, params=params)
            # 接口返回兜底,无items字段时返回空列表
            results = safe_get(r.json(), 'items', default=[])

            for result in results:
                volume_info = safe_get(result, 'volumeInfo', default={})
                # ISBN取值直接通过路径取,缺对应索引自动返回None
                isbn_one = safe_get(volume_info, 'industryIdentifiers', 0, 'identifier')
                isbn_two = safe_get(volume_info, 'industryIdentifiers', 1, 'identifier')

                book_data = {
                    'title': safe_get(volume_info, 'title'),
                    'authors': safe_get(volume_info, 'authors', 0),
                    'publish_date': safe_get(volume_info, 'publishedDate'),
                    'isbn_one': isbn_one,
                    'isbn_two': isbn_two,
                    'page_count': safe_get(volume_info, 'pageCount'),
                    'thumbnail': safe_get(volume_info, 'imageLinks', 'thumbnail'),
                    'country': safe_get(result, 'saleInfo', 'country')
                }

                book_import.append(book_data)

    else:
        filter_ch = BookFilterForm()
    return render(request, "BookApp/book_import.html", {'book_import': book_import,
                                                        'filter_ch': filter_ch})

可选:ISBN特殊处理

如果你需要按ISBN类型(ISBN_10/ISBN_13)取值而非按索引取,可以在循环内补充以下逻辑:

# 构造ISBN类型到值的映射
isbn_map = {}
industry_ids = safe_get(volume_info, 'industryIdentifiers', default=[])
for item in industry_ids:
    id_type = safe_get(item, 'type')
    id_val = safe_get(item, 'identifier')
    if id_type and id_val:
        isbn_map[id_type] = id_val

# 按类型取ISBN,不存在则为None
isbn_10 = isbn_map.get('ISBN_10')
isbn_13 = isbn_map.get('ISBN_13')

内容的提问来源于stack exchange,提问作者Hide856

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 09:57:03