问题描述
我尝试了解如何在 pyright 中使用 TypeVar
。
我构建了以下小函数:
import random
from typing import List,Sequence,TypeVar
T = TypeVar("T",int,str,float)
TypedList = List[T]
def merge(a: TypedList,b: TypedList) -> TypedList:
i0,i1 = 0,0
merged = []
# Run with two pointers
while i0 < len(a) and i1 < len(b):
merged.append(min(a[i0],b[i1]))
if merged[-1] == a[i0]:
i0 += 1
else:
i1 += 1
# Add the tail
if i0 >= len(a):
merged.extend(b[i1:])
if i1 >= len(b):
merged.extend(a[i0:])
return merged
它让pyright在线抱怨:
merged.append(min(a[i0],b[i1]))
因为:
“min”没有重载匹配提供的参数
参数类型:(TypedList[int],TypedList[int])
[Pyright:reportGeneralTypeIssues]
此外,它抱怨:
if merged[-1] == a[i0]
因为:
预期的类类型,但收到“int”
和:
非法类型注释:不允许变量,除非它是类型别名
mypy 似乎在这条线上工作得很好。 关于问题是什么以及我如何解决它的任何想法?
谢谢!
解决方法
使用“联合”而不是“TypeVar”
import random
from typing import List,Sequence,TypeVar,Union
U = Union[int,str,float]
TypedList = List[U]
def merge(a: TypedList,b: TypedList) -> TypedList:
i0,i1 = 0,0
merged = []
# Run with two pointers
while i0 < len(a) and i1 < len(b):
merged.append(min(a[i0],b[i1]))
if merged[-1] == a[i0]:
i0 += 1
else:
i1 += 1
# Add the tail
if i0 >= len(a):
merged.extend(b[i1:])
if i1 >= len(b):
merged.extend(a[i0:])
return merged
在使用 'TypeVar' 时,如 'T = TypeVar(...)',所有 T 都应该是相同的类型。所以,pyright 搞糊涂了。在这种情况下,您应该使用“联合”,因为“U”不一定是相同的类型。
或者像这样
import random
from typing import List,TypeVar
T = TypeVar("T",int,float)
def merge(a: list[T],b: list[T]) -> list[T]:
i0,b[i1]))
if merged[-1] == a[i0]:
i0 += 1
else:
i1 += 1
# Add the tail
if i0 >= len(a):
merged.extend(b[i1:])
if i1 >= len(b):
merged.extend(a[i0:])
return merged