gpt4 book ai didi

python - Pylance 要求在一致的列表变量上显式类型

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

我将类型定义为 Literal 字符串的 Union

Color = Literal[
"red",
"green",
"blue",
"yellow",
"orange",
"purple"
]

我有一个函数需要一个符合类型的字符串列表。

def f(colors: List[Color]):
...

我实例化一个符合要求的字符串列表并将其传递给函数

colors = ['blue', 'green']

f(colors)

Pylance red 在函数调用中画出波浪线

Argument of type "list[str]" cannot be assigned to parameter "colors" of type "List[Color]" in function "f"
"list[str]" is incompatible with "List[Color]"
TypeVar "_T@list" is invariant
Type "str" cannot be assigned to type "Color"
"str" cannot be assigned to type "Literal['red']" Pylance(reportGeneralTypeIssues)

如果我明确注释实例化列表,警报就会消失

colors: List[Color] = ['blue', 'green']

这似乎是多余的。无论我是否对其进行注释,该列表都匹配预期的类型。类型系统不应该承认这一点吗?

事实上,我可以在没有警告的情况下直接传递列表

f(['blue', 'green']) # Pylance allows

Pylance 对此也很好

def f(seven: Literal[7]):
...

x = 7
f(x) # Pylance allows, doesn't require doing x: int = 7

所以它似乎只提示列表变量,而不是一般的隐式类型变量。

为什么我必须显式注释其值绝对符合预期类型的​​列表变量?

最佳答案

Python 字面量,例如 'blue'7 , 具有自然类型。 'blue'str , 和 7是一个 int ,根据它们的运行时类型。 Type Literals 可能会对此造成一些混淆,因为虽然它们采用特定对象并赋予它们额外的语义含义(例如 'blue'Color7f() 的参数),但它们不会覆盖默认值假定类型,并且仅在必要时锁定为变量的真实类型。

这如何导致您遇到的行为?让我们来处理 7第一的。在x = 7之后, x 的隐式自然类型不是“与 f() 兼容的类型”,它是 int .该隐式类型在 f(x) 期间成功缩小,但仅在该确切调用的上下文中,并且仅因为 Pylance 知道 x合法地可以缩小到 7 .

与此同时,对于 colors = ['blue', 'green'] ,Pylance 只担心为 colors 提出正确的类型.根据文字,它首先看到它是一个列表,然后它是一个字符串列表。因此推断的类型是 list[str] .现在,这可以缩小到 list[Color]当我们到达 f(colors) ?不,因为列表是可变的。没有运行时保证列表不会以其他字符串结尾,因此列表中的文字不能缩小为颜色。同样,作为对比,7是一个不可变的 int , 所以我们知道不能有任何其他东西与 7 一起存储在 x 内.那么为什么 f(['green', 'blue'])工作?因为在这种情况下列表的生命周期只是函数调用本身,所以有一个隐式请求使列表尽可能与调用签名兼容,而不用担心调用者代码稍后可能会尝试对列表做什么(因为它根本不能做任何事情)。

那么如何绕过呢?首先是您注意到的,明确将列表限制为 Colors .您还可以使用不可变类型,例如元组,因为 Python 知道,就像在函数调用中生成的列表一样,对象在运行时不会更改:

Color = Literal['red', 'blue']

def f(colors: Sequence[Color]): ...

L = ['red', 'blue']
f(L) # fails!
T = ('red', 'blue')
f(T) # succeeds!

关于python - Pylance 要求在一致的列表变量上显式类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74145111/

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