Parent
's mymethod
声称至少采用 0 个关键字参数。要理解这一点,请看一下这个示例:
def mymethod(**kwargs) -> None:
pass
mymethod()
mypy
报告此操作成功,因为不需要命名关键字参数。len(kwargs)
这里是 0。
你的例子表明Child
's mymethod
至少需要 1 个关键字参数,因为arg1
是被迫提供的。为了:
def mymethod(*, named_kwarg, **kwargs) -> None:
pass
mymethod()
mypy
报告:
error: Missing named argument "named_kwarg" for "mymethod"
您现在明白为什么会出现错误了吗?你的Parent
's mymethod
声明至少 0 个关键字参数。你的Child
s mymethod
至少声明 1 个关键字参数。里氏替换原则说超类的实例应该可以用子类的实例替换,但由于子类比超类提出了更严格的要求,mypy
您的类型层次结构的错误。
If mypy
报告成功,如果实例传递 0 个关键字参数将导致运行时错误Parent
您正在处理的也恰好是一个实例Child
.
为了进一步阐明这一点,如果我们改变Child
's mymethod
签名至:
def mymethod(self, *, arg1: Optional[int] = None, **kwargs) -> None:
...
mypy
现在显示您的层次结构没有错误。这是因为我们已经声明了mymethod
现在至少采用 0 个关键字参数而不是 1 个,使其像Parent
根据里氏替代原理要求。