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

时间:2018-06-15 10:43:52

标签: python python-3.x

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

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)

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

return [NewsItem.from_payload(hit['_source'])
        for hit in result['hits']['hits']]

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

3 个答案:

答案 0 :(得分:2)

我认为最优雅的方法是使用._fields的{​​{1}}:

NewsItem

如果你想保留额外内容,你需要做一些工作(字段@classmethod def from_payload(cls, payload) -> 'NewsItem': return cls(*(payload[field] for field in cls._fields)) 声明为extra):

extra: dict = {}

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

当然,我的解决方案无法处理@classmethod def from_payload(cls, payload) -> 'NewsItem': fields_no_extra = set(cls._fields) - {'extra'} extra_fields = payload.keys() - fields_no_extra extras = {field: payload[field] for field in extra_fields} data = {field: payload[field] for field in fields_no_extra} data['extra'] = extras return cls(**data) 不包含payload

的所有字段的情况

答案 1 :(得分:1)

您可以使用**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回答+评论)

答案 2 :(得分:0)

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

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

所以,请执行以下操作

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

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