使用 getter-setter 创建 class,使用 python3 从 json 获取数据

Create class using getter-setter which gets data from json using python3

我正在为第 3 方应用程序使用 REST APIs 构建应用程序。当我从 API 中检索一个对象时,它会向我发送一个 json,我将其传递给一个 class,该 class 在内部取出密钥并使用 [= 通过 class 提供数据22=]

示例:

有效载荷:

{
  "value":{
    "boot":{
      "delay":10,
      "legacy_boot":false
    }
  }
}
class AbstractInfo:
  def __init__(self, json):
    try:
      self.info = json["value"]
    except KeyError:
      # KeyError is raised when nested dictionary is passed which does not contain `value` key
      self.info = json

  def to_dict(self):
    return self.info

class BootInfo(AbstractInfo):

  @property
  def delay(self):
    return self.info["delay"]

  @property
  def legacy_boot(self):
    return self.info["legacy_boot"]

class MainInfo(AbstractInfo):
  @property
  def boot(self):
    return BootInfo(json=self.info["boot"])

现在,我从其他进程调用 MainInfo class 使用动态导入并执行类似这样的操作

# Do rest API call and get the payload in a variable
MainInfo(json=payload)

到目前为止一切正常,我只是想像这样从有效负载中获取值

# GetInfo does dynamic import for the correct class based on the resource_id
info = GetInfo("resource_id")
print(info.boot.delay)

现在,我的 objective 是使用 BootInfo 中定义的模式创建一个对象,以便 returns 相关 dictionary.

这里是打印语句的结果,可以帮助解决问题

print(MainInfo(json=json).to_dict())

{'boot': {'delay': 10, 'legacy_boot': False}}

print(MainInfo(json=json).boot.to_dict())

{'delay': 10, 'legacy_boot': False}

我想做类似的事情

bi = BootInfo(delay=20, legacy_boot=True).build_dict()
print(bi)
{'delay': 20, 'legacy_boot': True}
# Then use `bi` into another place to mount the dictionary easily like building a lego set

我知道我的 BootInfo 不接受 delaylegacy_boot 作为参数。如果我添加它们,那么当数据通过 json 到达时如何设置值?我觉得我在这里处于先有鸡还是先有蛋的局面。而且,如果可能的话,我想保持代码的当前结构不变,这样从嵌套结构中查找键的工作就更少了。我拥有的嵌套结构越多,我制作的 classes 就越多。当某个键依赖于另一个 属性 的值并且在 json 有效负载中可能不可用时,我也在属性下进行验证。

我研究了 gettersetter 并尝试了一些东西并遇到了几个问题,但无法满足我的要求。

有谁知道完成这项工作的最佳方法或用示例代码告诉我正确的方向吗?

我认为这是何时使用验证程序库的主要示例。 (个人最爱:https://pydantic-docs.helpmanual.io/

优点:

  1. 您可以通过强类型预期的 json 和嵌套结构来验证您​​通过 API 获取的数据。
  2. 它具有将 dict 转换为 class 和将 class 转换为 dict 的所有辅助方法,以及必要时读取 json 字符串的方法。

示例:

from pydantic import BaseModel

class BootInfo(BaseModel):
  delay: int
  legacy_boot: bool

class MainInfo(BaseModel):
  boot: BootInfo


class Info(BaseModel):
  value: MainInfo

那么你可以这样做:

payload = {
  "value":{
    "boot":{
      "delay":10,
      "legacy_boot":false
    }
  }
}

info = Info(**data)
info.value.boot.delay
info.value.boot.legacy_boot

assert info.dict() == payload

# or init the class by properties
boot_info = BootInfo(delay=10, legacy_boot=False)
assert boot_info.delay == 10
boot_info.dict()