为什么类型联合不解析为 Python 中的受约束泛型?
Why does Union of types not resolve to the constrained generic type in Python?
我有下面的例子。
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)
:
中抱怨以下内容
Argument of type "Sequence[int] | Sequence[str]" cannot be assigned to parameter "ids" of type "Sequence[IdentifierSymbol@f]" in function "f"
Type "Sequence[int] | Sequence[str]" cannot be assigned to type "Sequence[IdentifierSymbol@f]"
TypeVar "_T_co@Sequence" is covariant
Type "str" is not compatible with constrained type "int" PylancereportGeneralTypeIssues
我不确定如何解释这个,但听起来问题是 int 与 str 不兼容。但为什么在这种情况下这是一个问题?我有一个 str 序列或一个 int 序列,int 和 str 之间的兼容性从何而来?
至于mypy
,那么在当前版本(0.800)中,由于推导类型变量的特殊性(TypeVar
),这不起作用:当其类型从多个类型推导时(包括在 Union
和 Sequence
中使用的),它被简化为最接近的公共基类型。在这种情况下,当该公共基类型不包含在TypeVar 约束列表中时,将出现错误。
此行为 may change 在未来的版本中。
例如:
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
我有下面的例子。
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)
:
Argument of type "Sequence[int] | Sequence[str]" cannot be assigned to parameter "ids" of type "Sequence[IdentifierSymbol@f]" in function "f"
Type "Sequence[int] | Sequence[str]" cannot be assigned to type "Sequence[IdentifierSymbol@f]"
TypeVar "_T_co@Sequence" is covariant
Type "str" is not compatible with constrained type "int" PylancereportGeneralTypeIssues
我不确定如何解释这个,但听起来问题是 int 与 str 不兼容。但为什么在这种情况下这是一个问题?我有一个 str 序列或一个 int 序列,int 和 str 之间的兼容性从何而来?
至于mypy
,那么在当前版本(0.800)中,由于推导类型变量的特殊性(TypeVar
),这不起作用:当其类型从多个类型推导时(包括在 Union
和 Sequence
中使用的),它被简化为最接近的公共基类型。在这种情况下,当该公共基类型不包含在TypeVar 约束列表中时,将出现错误。
此行为 may change 在未来的版本中。
例如:
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