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

如何将Pexels API的requests响应JSON转为Python类对象

问题原因

你直接通过SearchResponse(**data)初始化响应对象时,仅顶层字段会被赋值为基础类型值,嵌套的字典(如src字段)、字典列表(如photos字段)仍然是原生Python dict/list类型,自然无法通过属性方式访问内部字段。另外注意Python列表索引从0开始,第一个元素是photos[0]而非photos[1]。

实现方案

两种常用实现方式,按需选择即可:

方案1:标准库dataclass(零依赖)

使用Python 3.7+内置的dataclass,通过__post_init__方法手动处理嵌套对象转换,不需要安装第三方依赖。
首先编写你的types.py:

from dataclasses import dataclass
from typing import List, Optional

# 最内层的图片尺寸链接类
@dataclass
class PhotoSrc:
    original: str
    large2x: str
    large: str
    medium: str
    small: str
    portrait: str
    landscape: str
    tiny: str

# 单张图片类
@dataclass
class Photo:
    id: int
    width: int
    height: int
    url: str
    photographer: str
    photographer_url: str
    photographer_id: int
    avg_color: str
    src: PhotoSrc
    liked: bool
    alt: str

# 搜索结果顶层响应类
@dataclass
class SearchResponse:
    total_results: int
    page: int
    per_page: int
    photos: List[Photo]
    next_page: Optional[str] = None

    def __post_init__(self):
        # 初始化后自动转换嵌套的列表和字典为对应类实例
        self.photos = [
            Photo(
                **item,
                src=PhotoSrc(**item["src"])
            ) for item in self.photos
        ]

你现有的search_photos方法不需要修改,直接返回SearchResponse(**data)即可实现属性访问。

方案2:Pydantic(自动转换,适合复杂接口)

如果接口嵌套层级深、字段多,推荐使用Pydantic库,它会自动递归完成所有嵌套结构的类型转换和校验,不需要手动写转换逻辑,非常适合写API封装。

  1. 先安装依赖:
pip install pydantic
  1. 编写types.py:
from pydantic import BaseModel
from typing import List, Optional

class PhotoSrc(BaseModel):
    original: str
    large2x: str
    large: str
    medium: str
    small: str
    portrait: str
    landscape: str
    tiny: str

class Photo(BaseModel):
    id: int
    width: int
    height: int
    url: str
    photographer: str
    photographer_url: str
    photographer_id: int
    avg_color: str
    src: PhotoSrc
    liked: bool
    alt: str

class SearchResponse(BaseModel):
    total_results: int
    page: int
    per_page: int
    photos: List[Photo]
    next_page: Optional[str] = None
  1. 修改search_photos里的返回逻辑,用Pydantic的模型校验方法加载数据:
def search_photos(
    self, 
    query: str, 
    orientation: str = "", 
    size:str = "",
    color: str = "",
    locale: str = "",
    page: int = 1,
    per_page: int = 15,
    **kwargs
) -> SearchResponse:
    # 用requests的params参数自动处理url编码,避免特殊字符请求错误
    params = {k:v for k,v in {
        "query": query,
        "orientation": orientation,
        "size": size,
        "color": color,
        "locale": locale,
        "page": page,
        "per_page": per_page
    }.items() if v}
    data, req = self._make_request("search", params=params)
    # pydantic v2用model_validate,v1版本替换为parse_obj即可
    return SearchResponse.model_validate(data)
使用效果

两种方案实现后,都可以流畅通过属性访问任意层级字段:

resp = client.search_photos("nature")
print(resp.total_results) # 输出总结果数
print(resp.photos[0].alt) # 输出第一张图片的alt文本
print(resp.photos[0].src.original) # 输出第一张图片的原图链接
print(resp.next_page) # 输出下一页地址

额外提示:你当前直接拼接query字符串的写法存在隐患,遇到查询词包含空格、&等特殊字符时会出现请求错误,建议统一通过requests的params参数传递URL查询参数,会自动完成URL编码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:18:35