问题
(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
?请注意,这具体是一个打字问题,我可以扩展字典。
我尝试过的内容
列表理解
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
也不应该起作用。 Base
与Child
不一致。请参阅this post了解详情。
关于python - 如何向 TypedDicts 列表中的每个字典添加键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75313958/