Python class 允许惰性 API 调用和两种类型的构造

Python class that allows for lazy API calls and two types of construction

我一直致力于为现有 REST API 创建 python 模块的项目。 API 基本上是获取有关巴西官方地理位置的数据。

出于简化原因,假设我们有 classes:RegionsRegionRegions 负责从 API 中收集所有国家地区并生成 Region 对象的列表。用户应该能够使用这两个 classes 来获取信息。现在我有几个问题:

  1. 如果用户想直接使用Region创建一个国家特定地区的对象,我应该如何限制对象的创建只允许存在的地区,避免代表一个不存在的区域的对象?我是否应该每次都查询 API 以检查该区域是否存在?我应该只允许 ID 为 1 到 5 的 Region

  2. 我想进行懒惰的 API 调用。也就是说,调用只有在之前从未发生过的情况下才会发生。这是最好的方法(下图)吗? (不知道这是不是懒惰的定义,但这里的目标是尽量减少调用)。

  3. 当我从 Regions class 中创建一个 Region 对象时,我已经拥有创建每个 Region 所需的所有信息.但是如果用户直接实例化Region,我还没有调用。我应该如何构建区域 class 以允许这两种方法?从 Regions class.

  4. 中创建 Region 对象时,我不想再次调用 API

下面提供了简化代码:

class Region():
    def __init__(self, id_=None, code=None, name=None):
        self.id = id_
        self.code = code
        self.name = name

    def __repr__(self):
        return f"Region(id_={self.id}, name=\"{self.name}\", code=\"{self.code}\")"


class Regions():
    def __init__(self):
        self.__ran_once = False
        self.result = None
        self.content = None
        self.json = None

    def __get(self):
        self.json = HttpClient.get("regioes")

        self.content = []
        for obj in self.json:
            self.content.append(
                Region(obj["id"], obj["sigla"], obj["nome"])
            )

    def all(self, format_json=False):
        if not self.__ran_once:
            self.__get()
            self.__ran_once = True

        if format_json:
            return self.json

        return self.content

    def names(self):
        if not self.__ran_once:
            self.__get()
            self.__ran_once = True

        return [r.name for r in self.content]

我不鼓励用户直接实例化 Region。如果他们这样做,后果自负。你可以把它放在文档字符串中。

您所描述的是缓存,而不是懒惰。我会这样写区域 class:

from cached_property import cached_property


class Regions:
    @cached_property
    def json(self):
        return HttpClient.get("regioes")

    @cached_property
    def content(self):
        return [
            Region(obj["id"], obj["sigla"], obj["nome"])
            for obj in self.json
        ]

    @cached_property
    def names(self):
        return [r["name"] for r in self.json]

安装 cached_propertypip install cached-property