如何在python中安全地解压dict?

2024-06-16 11:10:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包装类-它是我从后端返回到前端的抽象。在

from typing import NamedTuple

class NewsItem(NamedTuple):
    id: str
    title: str
    content: str
    service: str
    published_at: datetime

    @classmethod
    def from_payload(cls, payload) -> 'NewsItem':
        return cls(**payload)

例如,当我从elastic获取数据时,我将其转换为NewsItem

^{pr2}$

问题是我不想因为弹性的未知域而失败。如何忽略它们(或放入单独的专用属性列表NewsItem.extra)?在


Tags: fromimportidtypingtitleservicecontentnamedtuple
3条回答

我认为最优雅的方法是使用._fieldsNewsItem

@classmethod
def from_payload(cls, payload) -> 'NewsItem':
    return cls(*(payload[field] for field in cls._fields))

如果您想保留extra,则需要做一些工作(字段extra声明为extra: dict = {}):

^{pr2}$

你可以进一步优化这一点,用集合计算太多;)

当然,我的解决方案不处理payload不包含{}的所有字段的情况

由于您的问题在于未知密钥,所以可以使用字典的get方法安全地忽略未知密钥。在

对于get方法,第一个参数是要查找的键,第二个参数是在找不到键时将返回的默认值。在

所以,请执行以下操作

return [NewsItem.from_payload(hit['_source'])
        for hit in result.get('hits',{}).get('hits',"NOT FOUND"):

以上只是一个例子。当命中没有你想要的密钥时,一定要修改你想得到的东西。在

您可以使用**kwargs让您的__init__接受任意数量的关键字参数(“kwargs”表示“关键字参数”),并丢弃不必要的参数:

class NewsItem(NamedTuple):
    id: str
    title: str
    content: str
    service: str
    published_at: datetime

    @classmethod
    def from_payload(cls, id=None, title=None, content=None, service=None, published_at=None, **kwargs) -> 'NewsItem':
        return cls(id, title, content, service, published_at)

具有自省NamedTuple类属性的替代解决方案(参见@MOROZILnic answer+comment)

相关问题 更多 >