mypy 通用子类导致不兼容的类型
mypy generic subclass leads to incompatible types
我正在尝试使用类型提示实现幺半群。为此,我写了:
M = TypeVar('M')
class Monoid(Generic[M]):
...
def append(self, m: 'Monoid[M]') -> 'Monoid[M]':
raise NotImplementedError()
在子类中使用它时,例如
A = TypeVar('A')
class List(Monoid[A], Generic[A]):
def __init__(self, *values: A) -> None:
self._values = tuple(values)
...
def append(self, m: 'List[A]') -> 'List[A]':
return List(*(self.values + m.values))
我得到 error: Argument 1 of "append" incompatible with supertype "Monoid"
。由于 List
是 Monoid
的适当子类,我希望它能够键入。我做错了什么?
好吧,你的 List
class 不是 Monoid 的正确子类型。毕竟,您声明所有 Monoid 都必须有一个 append 方法,该方法可以接受任意 Monoid 或 Monoid 的 subclass —— 那么,为什么可以缩小 List 使其 append
只能接受具体列表?
这违反了 Liskov substitution principle。
您可以使用 generic self:
来解决这个特殊情况
M = TypeVar('M')
T = TypeVar('T')
class Monoid(Generic[M]):
...
def append(self: T, m: T) -> T:
raise NotImplementedError()
现在,您表示 Monoid
的所有子class 必须实现一个 append
方法,该方法专门接受任何子class 类型。使用这个新版本的 Monoid,您的列表 class 现在是类型安全的。
我正在尝试使用类型提示实现幺半群。为此,我写了:
M = TypeVar('M')
class Monoid(Generic[M]):
...
def append(self, m: 'Monoid[M]') -> 'Monoid[M]':
raise NotImplementedError()
在子类中使用它时,例如
A = TypeVar('A')
class List(Monoid[A], Generic[A]):
def __init__(self, *values: A) -> None:
self._values = tuple(values)
...
def append(self, m: 'List[A]') -> 'List[A]':
return List(*(self.values + m.values))
我得到 error: Argument 1 of "append" incompatible with supertype "Monoid"
。由于 List
是 Monoid
的适当子类,我希望它能够键入。我做错了什么?
好吧,你的 List
class 不是 Monoid 的正确子类型。毕竟,您声明所有 Monoid 都必须有一个 append 方法,该方法可以接受任意 Monoid 或 Monoid 的 subclass —— 那么,为什么可以缩小 List 使其 append
只能接受具体列表?
这违反了 Liskov substitution principle。
您可以使用 generic self:
来解决这个特殊情况M = TypeVar('M')
T = TypeVar('T')
class Monoid(Generic[M]):
...
def append(self: T, m: T) -> T:
raise NotImplementedError()
现在,您表示 Monoid
的所有子class 必须实现一个 append
方法,该方法专门接受任何子class 类型。使用这个新版本的 Monoid,您的列表 class 现在是类型安全的。