Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么类型的联合不能解析为Python中受约束的泛型类型?_Python_Python 3.x_Typing_Python Typing - Fatal编程技术网

为什么类型的联合不能解析为Python中受约束的泛型类型?

为什么类型的联合不能解析为Python中受约束的泛型类型?,python,python-3.x,typing,python-typing,Python,Python 3.x,Typing,Python Typing,我有下面的例子 from typing import Union, TypeVar, Dict, Sequence IdentifierSymbol = TypeVar("IdentifierSymbol", str, int) def f(ids: Sequence[IdentifierSymbol]) -> Dict[int, IdentifierSymbol]: return dict(zip(range(len(ids)), ids)) def

我有下面的例子

from typing import Union, TypeVar, Dict, Sequence

IdentifierSymbol = TypeVar("IdentifierSymbol", str, int)

def f(ids: Sequence[IdentifierSymbol]) -> Dict[int, IdentifierSymbol]:
    return dict(zip(range(len(ids)), ids))


def g(ids: Union[Sequence[int], Sequence[str]]) -> int:
    x = f(ids)
    return 1

PyLance(我猜在内部使用mypy)抱怨行
x=f(ids)


我不知道如何解释这一点,但听起来问题是int与str不兼容。但为什么在这种情况下会出现这个问题?我有一个str序列或一个int序列,int和str之间的兼容性从何而来?

至于
mypy
,那么在当前版本(0.800)中,由于推导类型变量()的特性,这不起作用:当它的类型从多个类型推导出来时(包括在
Union
Sequence
中使用),它被简化为它们最接近的公共基类型。在这种情况下,当此公共基类型未包含在TypeVar约束列表中时,将出现错误

在将来的版本中,此行为将被禁用

例如:

class A: ...

class B(A): ...

class C(A): ...

T = TypeVar("T")

def foo(var1: T, var2: T) -> T:
    return var1
    
reveal_type(foo(B(), C()))  # Revealed type is 'main.A*'

def bar(var: T) -> T:
     return var

def baz(var: Union[A, B]):
    reveal_type(bar(var))  # Revealed type is 'main.A*'

def qux(var: Sequence[T]) -> T:
    return var[0]

def quux(var: Tuple[A, B]):
    reveal_type(qux(var))  # Revealed type is 'main.A*'

def quuux(var: Union[Sequence[A], Sequence[B]]):
    reveal_type(qux(var))  # Revealed type is 'main.A*'
您需要使用其他类型注释,例如使
g
函数也通用。也许有人会建议一个更优雅的解决方案

def g(ids: Sequence[IdentifierSymbol]) -> int:
    x = f(ids)
    return 1

请注意,mypy失败,这里有一个不同的错误:“f”的类型变量“IdentifierSymbol”的值不能是“object”.IIRC MyPy通过超类型而不是并集解析两种类型可居住的变量。这回答了你的问题吗?@MisterMiyagi-Huh我猜PyLance有自己的类型检查器。对此感到惊讶。很可能并集[Sequence[int],Sequence[str]]解析为Sequence[object]或者类似的东西,然后什么也找不到。哦,这很有趣,所以基本上我的并集[Sequence[int],Sequence[str]]变成了Sequence[object]或者诸如此类?奇怪。如果我重载初始函数而不是使用TypeVar,看起来也会发生这种情况,所以我猜Union正在做一些奇怪的事情?遗憾的是,如果我在函数签名中只使用一次TypeVar,PyLance不喜欢它。但它确实会使函数体中的类型警告消失。“遗憾的是,如果我在函数签名中只使用一次TypeVar,PyLance不喜欢。”这条规则对我来说有些模糊。我会通过
#type:ignore
禁用它
def g(ids: Sequence[IdentifierSymbol]) -> int:
    x = f(ids)
    return 1