gpt4 book ai didi

python - 为什么 mypy `cast` 只在某些时候有效?

转载 作者:行者123 更新时间:2023-12-05 07:30:05 27 4
gpt4 key购买 nike

首先我做了一个愚蠢的小类

# cheese_helpers.py
class Cheese:
pass

然后这件事发生了

# weird.py

import lxml
from typing import cast, List
import cheese_helpers

o: List[Any] = []
reveal_type(o) # builtins.List[Any] as expected

y = cast(List[cheese_helpers.Cheese], o)
reveal_type(y) # builtins.List[cheese_helpers.Cheese], as expected

# so far so good. And then:

z = cast(List[lxml.html.HtmlElement], o)
reveal_type(z) # builtins.List[Any] ???????????????

如果您问我,最后一行应该是 List[lxml.html.HtmlElement]。奶酪也没有注释,但效果很好。

我确定要使最后一行工作,我需要获取/制作一些 lxml 注释。但是我的 cast 被完全忽略了,这对我来说似乎很奇怪。我转换到 Cheese 类并且它有效。我转换到 HtmlElement 类,但它没有。

我的问题是为什么?

最佳答案

您是否正在使用旧版本的 mypy?当我尝试使用 mypy 0.630(pypi 上的最新版本)和他们的 git master 分支上的最新代码对您的代码进行类型检查时,我得到了 builtins.list[Any] 的显示类型三种情况。

希望这种揭示的类型更直观一些——问题是不幸的是,typeshed 上的lxml 库没有可用的 stub 。 ,这意味着 mypy 没有关于 html.HtmlElement 到底是什么的信息。 (据 mypy 所知,这可能是一个类、一个函数、一个变量、一个类型别名、一个命名元组……)

因此,它放弃并假定它具有 Any 类型。

这也解释了为什么将 get_some_relevant_elements 的输出分配给 List[bool] 可以毫无错误地工作。 List[Any] 类型的变量理论上可以包含任何内容,包括 bool 值——所以也许这是一个安全的赋值。


无论如何,如果您不喜欢这种行为,您的两个选择是:

  1. 接受 lxml 库没有类型提示/是纯动态类型的事实,并设计您的代码,以便所有这些动态都包含在一个位置。当您从 XML 文件中提取信息时,(可选)验证它们并返回您自己的自定义、带注释的类。基本上,故意在代码库的动态部分和非动态部分之间设置一个屏障。

  2. 为 lxml 创建您自己的 stub 。这些 stub 不一定需要很复杂——只需为您需要的几个类和方法创建初步 stub 就足够了。 (如果它们最终变得相当充实,如果您愿意的话,您也许可以开源它们并回馈社区。)

关于python - 为什么 mypy `cast` 只在某些时候有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52499243/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com