我正在尝试在高效功能(试图避免复制)中执行以下(简化示例),而不使用NotRequired
(原因如下所示):
Mytd1 = TypedDict("Mytd1", {a: NotRequired[str], x: int})
Mytd_extra = TypedDict("Mytd_extra", {a: str, x: int, z: str})
def foo(y: Mytd1) -> Mytd_extra:
# users input object should NOT contain z
y = cast(Mytd_extra, y). # fails - my guess is `a` is the offender
y["z"] = "hooray"
if "a" not in y:
y["a"] = "whatever"
return y
Mypy 抱怨强制转换为“分配中不兼容的类型”,但这是我想要做的。我如何实现这一目标?我认为a
是违规者 - 输出类型需要它
我不想:
# kill Mytd1
Mytd_extra = TypedDict("Mytd_extra", {x: int, z: NotRequired[str]})
因为这将允许客户通过,{x: 5, z: "asdf"}
但foo
应该禁止 - 他们只允许通过{x: 5}
。
我认为以下是可行的,但我试图避免它以提高效率,因为这个函数被多次调用:
def foo(y: Mytd1) -> Mytd_extra:
new_var: Mytd_extra = {k: v for k:v in y.items()}
new_var["z"] = "ohno"
return new_var
您至少有两个完全有效的解决方案(假设 python 3.11 不打扰typing
vs typing_extensions
,如果需要调整您的导入)。问题是它y
是 type Mytd1
,所以你不能给Mytd_extra
它赋值(转换结果)。
from typing import TypedDict, NotRequired, cast
Mytd1 = TypedDict("Mytd1", {'a': NotRequired[str], 'x': int})
Mytd_extra = TypedDict("Mytd_extra", {'a': str, 'x': int, 'z': str})
def foo(orig_y: Mytd1) -> Mytd_extra:
# users input object should NOT contain z
y = cast(Mytd_extra, orig_y)
y["z"] = "hooray"
if "a" not in y:
y["a"] = "whatever"
return y
这是具有此解决方案的游乐场。
保留您的原始代码,但使用--allow-redefinition
(或添加allow_redefinition = true
到您使用的配置文件)运行:playground。
警告: allow_redefinition
没有 Super Cow Powers,它的用例仅限于单一场景:当 RHS 中的表达式包含此变量时,分配给预定义变量。它允许以下操作:
y = 'abc'
y = list(y)
但不是这个:
y = 'abc'
y = 1
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句