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

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)?

最佳答案

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

@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不包含NewsItem所有字段的情况

关于python - 如何在python中安全解压缩dict?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50873976/

10-12 07:32