python - 如何向 TypedDicts 列表中的每个字典添加键

标签 python python-3.x python-typing

问题

(Python 3.9)我有一些继承的TypedDict s,如下:

from typing import TypedDict


class Base(TypedDict):
    key: str


class Child(Base):
   extended: str

我有一个 Base 字典列表,我想将其扩展为 Child 字典,每个字典具有相同的值。

base_list: list[Base] = [{'key': 'value'}, {'key': 'value2'}]

最后我想要以下内容:

child_list: list[Child] = [
  {'key': 'value', 'extended': 'sameval'}, 
  {'key': 'value2', 'extended': 'sameval'}
]

我正在使用 pylance/pyright。

关于如何优雅地完成此任务的任何建议/无需 cast ?请注意,这具体是一个打字问题,我可以扩展字典。

我尝试过的内容

列表理解

This response建议:

child_list: list[Child] = [dict(base,extended='ex') for base in base_list]

但是,皮兰斯提示道:

Expression of type "list[dict[str, object]]" cannot be assigned to declared type "list[Child]"

我可以通过cast解决这个问题,但感觉很脏:

a_ex: list[Child] = [cast(Child, dict(base,extended='ex')) for base in a]

NotRequired

我认为我可以通过将 extend 标记为 NotRequired 来解决它,然后迭代列表以设置 key 。任何Base 对象都应该是有效的Child 对象,对吧?不。

a_ex: list[Child] = a
Expression of type "list[Base]" cannot be assigned to declared type "list[Child]"
  "list[Base]" is incompatible with "list[Child]"
    TypeVar "_T@list" is invariant
      "extended" is missing from "Type[Base]"

我也玩过 dict.update ,但遇到了与列表理解类似的问题。

最佳答案

为什么不显式初始化每个Child

from pprint import pprint
from typing import TypedDict


class Base(TypedDict):
    key: str


class Child(Base):
    extended: str


base_list: list[Base] = [{"key": "value"}, {"key": "value2"}]

child_list: list[Child]

child_list = [Child(key=d["key"], extended="sameval") for d in base_list]

pprint(child_list)

输出:

[{'extended': 'sameval', 'key': 'value'},
 {'extended': 'sameval', 'key': 'value2'}]

这通过了 mypy --strict 没有任何问题,如果 Pyright 对此有问题,我会感到惊讶。

需要明确的是,这两者也有效:(基于相同的原理)

child_list = [dict(key=d["key"], extended="sameval") for d in base_list]
child_list = [{"key": d["key"], "extended": "sameval"} for d in base_list]

您的第一次尝试不起作用,因为您不再处理字典文字或显式命名的参数,而是处理 for 循环中的变量 -- base 。我认为无法保证类型安全,因为字典是可变的,但如果可能的话,其他人可以在这里解决细节。

无论如何,为了以尽可能少的示例演示该问题,请考虑以下事项:

from typing import TypedDict


class Base(TypedDict):
    key: str


b1: Base = {"key": "value"}  # safe
b2: Base = dict(key="value")  # safe
b3: Base = dict(b1)  # not safe

通过 mypy 运行此命令仅在最后一行出现以下错误:

错误:赋值中的类型不兼容(表达式的类型为“Dict[str, object]”,变量的类型为“Base”)[赋值]

这类似于您在第一个列表理解示例中从 Pyright 收到的错误。类型检查器只能推断字典初始化的结果为 dict[str, object]


您第二次尝试使用 NotRequired 也不应该起作用。 BaseChild 不一致。请参阅this post了解详情。

关于python - 如何向 TypedDicts 列表中的每个字典添加键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75313958/

相关文章:

python - 有没有更好的方法来连接 Python 中的连续字符串元素?

python - 如何从 print(string, end =“, ” ) 中删除最后一个逗号

python-3.x - 内存游戏计时器实现和错误处理

python-3.x - 如何读取套接字缓冲区中的所有可用字节? Python3

Python 键入 : Mypy errors with overload "overlap" when signatures are different

python - notests 将导入的方法标记为非测试用例

python - 使用 pandas 数据框计算百分比变化的绝对值

带有kwargs的函数的python类型签名(typing.Callable)

python - 通过文件上传从模型生成表单

python - 一种为类型检查目的子类化 NamedTuple 的方法