我有以下简单的课程
class A:
pass
class B(A):
pass
我想要另一个类,
C
,其方法将接受A
的任何子类作为参数,默认为B
。我认为 Generic
是一个合适的候选人:
T = TypeVar('T', bound=A)
class C(Generic[T]):
def foo(self, assistant: type[T] = B) -> None:
pass
但是,当我运行 mypy 时,出现错误
参数“assistant”的默认值不兼容(默认值的类型为“type[B]”,参数的类型为“type[T]”
我觉得这有点令人困惑,因为我认为
TypeVar('T', bound=A)
的想法是创建一个与 A
的任何子类兼容的类型(所以特别是 B
)。
有人知道我在这里做错了什么吗?
你不需要泛型。你应该这样做
class C:
def foo(self, assistant: type[A] = B) -> None:
...
type[A]
已经是代表从 A
派生的所有类的类型(包括 A
)。
您所做的是创建一个通用类。该类采用类型参数,例如
c: C[B] = C()
,并且 foo
的参数必须是该类型参数的后代。
根据你的类定义,如果你这样做的话
class D(A): pass
c: C[D] = C()
那么
c.foo
将需要 D
的后代作为参数。但是,默认值 B
不是 D
的后代,因此默认值将是无效参数,因此会出现错误消息。
问题是,如果
C[D]
继承自 D
,您可以定义类似 A
的内容。但在这种情况下 type[B]
不是 type[D]
的子类型(这将是参数的类型),因此 mypy 的抱怨是绝对正确的。