让我们考虑以下代码片段:
class A:
def foo(self) -> None:
raise NotImplementedError
class B(A):
def foo(self) -> None:
print("I'm B(A)")
class C(A):
def foo(self, x: int) -> None:
print(f"I'm C(A), x={x}")
bob = B()
bob.foo()
charly = C()
charly.foo(4)
运行时,它提供了预期的结果:
I’m B(A)
I’m C(A), x=4
但是 mypy 正在引发错误:
$ mypy subclass.py
subclass.py:10: error: Signature of « foo » incompatible with supertype « A » [override]
subclass.py:10: note: Superclass:
subclass.py:10: note: def foo(self) → None
subclass.py:10: note: Subclass:
subclass.py:10: note: def foo(self, x: int) → None
Found 1 error in 1 file (checked 1 source file)
这是一个糟糕的设计吗?除了简单地从父类中删除抽象方法之外,还有什么好的选择?
您始终可以使用
args
和 kwargs
来表明该函数可以接受任意数量的参数,并且由子类实现来决定参数的数量及其名称。
class A:
def foo(self, *args, **kwargs) -> None:
raise NotImplementedError
class B(A):
def foo(self) -> None:
print("I'm B(A)")
class C(A):
def foo(self, x: int) -> None:
print(f"I'm C(A), x={x}")
Mypy应该接受它。