Python 类型提示:子类与泛型不兼容

问题描述 投票:0回答:2

我有以下简单的课程

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
)。

有人知道我在这里做错了什么吗?

python python-3.x generics types type-hinting
2个回答
0
投票

你不需要泛型。你应该这样做

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
的后代,因此默认值将是无效参数,因此会出现错误消息。


0
投票

问题是,如果

C[D]
继承自
D
,您可以定义类似
A
的内容。但在这种情况下
type[B]
不是
type[D]
的子类型(这将是参数的类型),因此 mypy 的抱怨是绝对正确的。

© www.soinside.com 2019 - 2024. All rights reserved.