如何强制施法键入命令以避免分配中的不兼容类型
我正在尝试在高效率函数(试图避免复制)中执行以下(简化的示例),而无需使用Naborequired
(出于此后显示的原因):
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
是罪犯 - 在输出类型
i Do 不是 WANT上需要:
# 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
I am trying to do the following (simplified example) in a high efficiency function (trying to avoid copy), without using NotRequired
(for reasons shown after):
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 complains about the cast as "incompatible types in assignment", but it's what I want to do. How do I achieve this? I think a
is the offender - it's required on the output type
I do not want:
# kill Mytd1
Mytd_extra = TypedDict("Mytd_extra", {x: int, z: NotRequired[str]})
because this would allow the client to pass in {x: 5, z: "asdf"}
into foo
but that should be forbidden - they are only allowed to pass {x: 5}
.
I think the following would be doable but I'm trying to avoid it for efficiency as this function is called many times:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您至少有两个完全有效的解决方案(假设Python 3.11不要打扰
键入
vstyping_extensions
,请在需要时调整导入)。问题是y
是类型mytd1
,因此您无法分配mytd_extra
(cast的结果)。在这里使用另一个变量
是
允许重新定义(mypy flag)
保留您的原始代码,但使用
- allow-redefinition
(或添加ally_redefinition = true
true config config config config config您使用):警告:
allow_redefinition
没有超级牛的功率,用例仅限于单个方案:当rhs中的表达式包含此变量时,将其分配到预定变量。它允许以下内容:但不是这样:
You have at least two completely valid solutions (assuming python 3.11 not to bother with
typing
vstyping_extensions
, adjust your imports if needed). The problem is thaty
is of typeMytd1
, so you cannot assignMytd_extra
(result of cast) to it.Use another variable
Here is a playground with this solution.
Allow redefinition (mypy flag)
Preserve your original code, but run with
--allow-redefinition
(or addallow_redefinition = true
to config file you use): playground.Warning:
allow_redefinition
does not have Super Cow Powers, it's use case is limited to a single scenario: assignment to a pre-defined variable, when expression in RHS includes this variable. It allows the following:but not this: