Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在python中安全地解包dict?_Python_Python 3.x - Fatal编程技术网

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

如何在python中安全地解包dict?,python,python-3.x,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':

我有一个包装器类——它是一个从后端返回到前端的抽象

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获取数据时,我会将其转换为
新闻项目

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

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

由于您的问题在于未知键,因此可以使用字典的get方法安全地忽略未知键

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

因此,请执行以下操作

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

以上只是一个例子。当点击没有你想要的键时,一定要修改你想要的内容。

我认为最优雅的方法是使用
新闻项目的
字段:

return [NewsItem.from_payload(hit['_source'])
        for hit in result['hits']['hits']]
@classmethod
def from_payload(cls, payload) -> 'NewsItem':
    return cls(*(payload[field] for field in cls._fields))
如果您想保留extras,您需要做一些工作(字段
extra
声明为
extra:dict={}
):

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


当然,我的解决方案不能处理
有效负载
不包含
新闻项

的所有字段的情况。您可以使用
**kwargs
让您的
\uu init\uuu
接受任意数量的关键字参数(“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
类属性的替代解决方案(请参见@morozinic answer+comment)

您是否担心结果字典中的键?是的,
hit[''u source]
可以包含一些在
新闻项中不存在的额外字段。我想忽略它们,并且在
from\u payload
什么是
NamedTuple
?如果
点击['''u source']
包含一些其他键,而不是(
id、标题、内容、服务、发布位置
)怎么办?我想你的算法会失败的。嘿,我刚才告诉你如何在使用字典的时候使用自动防故障方法。所以,当你试图访问一个密钥时,使用get方法。我确实提到过,这只是回答中的一个例子。如果你想访问hit,只需执行,hit。get(“_source”,“NA”)你无法理解OP,也无法理解注释!“当然,我的解决方案不能处理
有效载荷
不包含
新闻项
的所有字段的情况。”是的,它包含,但有一点小小的更改:
**{field:payload.get(field)for field in cls.\u fields}
谢谢,但是我从输入import NamedTuple
@petrush中得到了
属性错误:无法覆盖NamedTuple属性\uuuu初始化\uuuuu
,请参见修复