[英]mypy generic subclass leads to incompatible types
I'm toying around with implementing monoids with type hinting.我正在玩弄带有类型提示的幺半群。 To that end I've written:为此,我写道:
M = TypeVar('M')
class Monoid(Generic[M]):
...
def append(self, m: 'Monoid[M]') -> 'Monoid[M]':
raise NotImplementedError()
When using this in a subclass, eg在子类中使用 this 时,例如
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))
I get error: Argument 1 of "append" incompatible with supertype "Monoid"
.我收到error: Argument 1 of "append" incompatible with supertype "Monoid"
。 Since List
is a proper subclass of Monoid
, I would expect this to be able to type.由于List
是Monoid
的适当子类,我希望它能够输入。 What am I doing wrong?我究竟做错了什么?
Well, your List
class isn't a proper subtype of Monoid.好吧,您的List
类不是Monoid 的正确子类型。 After all, you stated that all Monoids must have an append method that can accept any arbitrary Monoid or subclass of Monoid -- so, why is it ok to narrow List so that its append
can accept only specifically List?毕竟,您说过所有 Monoid 都必须有一个 append 方法,可以接受任意 Monoid 或 Monoid 的子类——那么,为什么可以缩小 List 的范围,使其append
只能接受特定的 List?
It's a violation of the Liskov substitution principle .这违反了Liskov 替换原则。
You can work around this specific case by using a generic self :您可以使用通用 self解决此特定情况:
M = TypeVar('M')
T = TypeVar('T')
class Monoid(Generic[M]):
...
def append(self: T, m: T) -> T:
raise NotImplementedError()
Now, you're expressing that all subclasses of Monoid
must implement an append
method that accepts specifically whatever that subclass type is.现在,您表示Monoid
所有子类都必须实现一个append
方法,该方法专门接受该子类的类型。 With this new version of Monoid, your List class is now typesafe.有了这个新版本的 Monoid,你的 List 类现在是类型安全的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.