我正在
list
之上编写一个非常薄的包装器,并且我想定义一个名为
reduce
的方法,但我正在努力正确注释它,以便
pylance
、
mypy
&
pylint
剪切它们每当我使用该方法,甚至定义它时,都会抱怨。
我很不安地意识到,Python 的内置库几乎没有类型注释。
这是我的实现尝试:
def reduce(self, func: Callable[[list[T], list[T]], list[T]] = lambda x, y: x + y, default: Optional[T] = None) -> 'List[T]': # type: ignore
from functools import reduce
if default is None: return List(reduce(func, self.list)) # type: ignore
return List(reduce(func, self.list, default)) # type: ignore
当我的
List
时,这会失败。实际上是一个字符串列表
a: List[str] = List(['a', 'b'])
b = a.reduce(lambda x, y: x + y)
显然,类型检查器和 linter 表示它们期望
list[T]
而我通过了
str
在类型注释中遇到了问题,因为为
functools.reduce
提供的
func
参数的类型提示不正确。
func
应该接受两个相同类型的参数并返回相同类型的单个值,而不是返回一个列表。
以下是的
reduce
方法的更正后的类型注释:
from typing import TypeVar, Callable, Optional, List
T = TypeVar('T')
class List(list, Generic[T]):
def reduce(self, func: Callable[[T, T], T], default: Optional[T] = None) -> T:
from functools import reduce
if default is None:
return reduce(func, self)
return reduce(func, self, default)
a: List[str] = List(['a', 'b'])
b = a.reduce(lambda x, y: x + y) # b 现在是 'ab'
此代码段中所做的更改:
-
更正
func
的类型提示:Callable[[T, T], T]
现在正确反映了func
应该接受两个类型为T
的参数并返回一个类型为T
的值的函数。 -
删除不必要的列表转换:
functools.reduce
已经返回一个单值,因此不需要List()
构造函数。 -
简化类型注释:
List[T]
可以简单地写成T
,因为reduce
返回一个单值,而不是一个列表。
使用这些更正,的代码现在应该可以被
pylance
、
mypy
和
pylint
正确类型检查,并且不会再出现错误。