强制类型标识的默认参数
Default argument enforcing type identity
我有自定义 class(实际上是 heapq
的简单包装器),它将接口包装成面向对象的接口并允许可选的 key
和 cmp
参数。
为了实现类型检查,我引入了 Tv
(堆中的值类型)和 Tk
("keys" 值的类型——即要执行的操作在堆内进行比较)。
因此 __init__
的注释如下所示:
from typing import *
Tv = TypeVar('Tv')
Tk = TypeVar('Tk')
class Heap(Generic[Tv, Tk]):
def __init__(self, initial: Optional[Iterable[Tv]],
key: Callable[[Tv], Tk] = lambda x: x, cmp: Callable[[Tk, Tk], bool] = op.lt):
pass
不幸的是,mypy
在这种情况下报告和错误:
error: Incompatible default for argument "key" (default has type "Callable[[Tv], Tv]", argument has type "Callable[[Tv], Tk]")
由于 Tk
的规范对于任何要使用 Heap
的人来说都没什么用,我试图完全放弃它——我制作了 Heap
subclass 只是 Generic[Tv]
并设置 Tk = Any
。这有很好的副作用,Heap
的用户不需要指定 Tk
类型,这与 Tv
基本相同,但我丢失了 [=16] 上的所有类型检查=] 在我的实现中。
有没有办法在 Heap
中保持 Tk
的类型检查并使 lambda x: x
的默认键值不引发错误?
编辑:当我试图使 Heap
subclass 只是 Generic[Tv]
并保留 Tk = TypeVar('Tk')
时,我仍然遇到错误
lambda x: x
的推断类型是 Callable[[Tv], Tv]
,因为函数中没有任何内容可以在 return 之前更改 x
的类型。这违反了类型提示,即参数和 return 类型可以任意变化。
解决方法是使用 cast
告诉 mypy
默认函数可以根据需要 "change" 其参数类型。
class Heap(Generic[Tv, Tk]):
def __init__(self,
initial: Optional[Iterable[Tv]],
key: Callable[[Tv], Tk] = lambda x: <b>cast(Tk, x)</b>,
cmp: Callable[[Tk, Tk], bool] = op.lt):
pass
然而,这基本上告诉 mypy
你知道自己在做什么,如果没有提供 key
函数,那么 you将确保 Tv
类型的值实际上可以用作 Tk
类型的值。通常,对于任意类型 Tv
和 Tk
.
,没有 类型为 Callable[[Tv], Tk]
的函数
我有自定义 class(实际上是 heapq
的简单包装器),它将接口包装成面向对象的接口并允许可选的 key
和 cmp
参数。
为了实现类型检查,我引入了 Tv
(堆中的值类型)和 Tk
("keys" 值的类型——即要执行的操作在堆内进行比较)。
因此 __init__
的注释如下所示:
from typing import *
Tv = TypeVar('Tv')
Tk = TypeVar('Tk')
class Heap(Generic[Tv, Tk]):
def __init__(self, initial: Optional[Iterable[Tv]],
key: Callable[[Tv], Tk] = lambda x: x, cmp: Callable[[Tk, Tk], bool] = op.lt):
pass
不幸的是,mypy
在这种情况下报告和错误:
error: Incompatible default for argument "key" (default has type "Callable[[Tv], Tv]", argument has type "Callable[[Tv], Tk]")
由于 Tk
的规范对于任何要使用 Heap
的人来说都没什么用,我试图完全放弃它——我制作了 Heap
subclass 只是 Generic[Tv]
并设置 Tk = Any
。这有很好的副作用,Heap
的用户不需要指定 Tk
类型,这与 Tv
基本相同,但我丢失了 [=16] 上的所有类型检查=] 在我的实现中。
有没有办法在 Heap
中保持 Tk
的类型检查并使 lambda x: x
的默认键值不引发错误?
编辑:当我试图使 Heap
subclass 只是 Generic[Tv]
并保留 Tk = TypeVar('Tk')
时,我仍然遇到错误
lambda x: x
的推断类型是 Callable[[Tv], Tv]
,因为函数中没有任何内容可以在 return 之前更改 x
的类型。这违反了类型提示,即参数和 return 类型可以任意变化。
解决方法是使用 cast
告诉 mypy
默认函数可以根据需要 "change" 其参数类型。
class Heap(Generic[Tv, Tk]):
def __init__(self,
initial: Optional[Iterable[Tv]],
key: Callable[[Tv], Tk] = lambda x: <b>cast(Tk, x)</b>,
cmp: Callable[[Tk, Tk], bool] = op.lt):
pass
然而,这基本上告诉 mypy
你知道自己在做什么,如果没有提供 key
函数,那么 you将确保 Tv
类型的值实际上可以用作 Tk
类型的值。通常,对于任意类型 Tv
和 Tk
.
Callable[[Tv], Tk]
的函数