我正在为第三方应用程序构建一个使用REST的应用程序。当我从API中检索一个对象时,它发送给我一个json,它传递给一个内部取出键并通过类使用property提供数据的类。
示例:
有效载荷:
{
"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类,并执行如下操作
# 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)现在,我的目标是使用BootInfo中定义的模式创建一个对象,以便它返回相关的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不接受delay和legacy_boot作为论据。如果我添加它们,那么当数据通过json到达时,如何设置值?我觉得我现在处于一种鸡皮疙瘩的境地。而且,如果可能的话,我希望保持代码的当前结构,这样从嵌套结构中找到键的工作就更少了。嵌套结构越多,生成的类就越多。当某个键依赖于来自另一个属性的值并且在json有效负载中可能不可用时,我也在属性下进行验证。
我研究过getter和setter,尝试了一些事情,并遇到了一些问题,只是无法使我的需求发挥作用。
有没有人知道最好的方法来完成这件事,或者用一个示例代码告诉我正确的方向?
发布于 2022-03-15 16:27:05
我认为这是关于何时使用验证器库的一个主要示例。(个人最爱:https://pydantic-docs.helpmanual.io/)
优势:
示例:
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()https://stackoverflow.com/questions/71485331
复制相似问题