通用列表联盟没有按我期望的方式工作

Posted

技术标签:

【中文标题】通用列表联盟没有按我期望的方式工作【英文标题】:Union of Generic List does not work the way I expect it 【发布时间】:2020-11-22 21:45:02 【问题描述】:

所以我有一个函数,它接受一个 obj 列表或一个 obj 并返回一个列表。

这是它的样子:

from typing import Union, List, TypeVar, Type

T = TypeVar('T')


def to_list(obj_type: Type[T], obj_or_list: Union[List[T], T]) -> List[T]:
    ...

如果我传入一个 str 就可以了。 例如

result: List[str] = to_list(str, "hi")

但是当我传入 str 列表(或任何对象的列表)时失败(通过 pyright 的类型检查错误) 例如

input_data: List[str] = ["hi"]
result: List[str] = to_list(str,input_data)

这是错误信息

类型“List[str | List[str]]”的表达式不能分配给声明的类型“List[str]”

看起来类型检查器 (pyright) 认为 to_list 正在返回 List[Union[List[str],str]] 而不仅仅是 List[str]

基本上不是将T 解释为str,而是将T 解释为Union[List[str], str] 这有点烦人,因为我认为确定 T 是 str 会足够聪明,因为我明确地将 str 传递为 obj_type

我的两个问题是:

有没有办法实现我想要的?基本上是一个函数,它接受对象列表或单个对象并返回对象列表(同时保留类型提示) 我目前的解决方法是这样的
from typing import Union, List, TypeVar, Type

T = TypeVar('T')


def to_list(obj_type: Type[T], obj_or_list: Any) -> List[T]:
    ...
是否有确定通用参数如何解析的技术名称?所以我可以搜索并了解它? 例如基本上,如果我将List[str] 传递给Union[List[T],T] 类型的参数,那么有两种可能性: TList[str] Tstr, 我想知道的是,确定T 是什么的过程是否有一个特定的/学术/技术名称

【问题讨论】:

我已复制粘贴您的代码并运行它,工作正常,没有出现任何错误。你用的是什么版本的python?我用 3.7 测试过 这不是一个真正的错误。它只是一个类型检查错误。我将 vscode 与 pylance 和 python 扩展一起使用 【参考方案1】: 部分回答我的第二个问题: 此过程的技术名称称为 TypeVar 匹配(有时也称为 TypeVar“求解”)。相关链接:https://github.com/microsoft/pyright/issues/910#issuecomment-667553334

【讨论】:

以上是关于通用列表联盟没有按我期望的方式工作的主要内容,如果未能解决你的问题,请参考以下文章

为啥 SQL 查询的结果没有按我期望的顺序返回?

我的 CodeIgniter 图像处理库没有按我想要的方式工作

django 中用于简单通用视图的 extra_context 函数

syslog-ng 匹配和过滤器没有按我想要的方式工作

php require_once 没有按我想要的方式工作.. 相对路径问题

我无法让 x 轴按我想要的方式工作