考虑以下最小示例:
class A:
def f(self): pass
class B(A): pass
class C(A): pass
class D:
def g(self): pass
class E(B,D): pass
class F(C,D): pass
AandD = ...
def h(obj: AandD): pass
我的示例中的类
A
可以有一个复杂的继承树,其中包含许多子类(B
、C
等)。我希望 A
的子类的某些实例具有附加功能 g
,因此我引入了另一个类 D
并使用多重继承来定义 E
和 F
。
如何正确注释函数
obj
的参数h
,它应该同时接受从A
和D
继承的实例,即,应该用什么来代替AandD
?
我知道我可以定义一个协议:
from typing import Protocol
class AandD(Protocol):
def f(self): pass
def g(self): pass
但是我想避免代码中的重复,因为我的类包含很多方法。而且它不适用于 3.8 之前的 Python 版本。
我还想避免使用
Union[E,F]
,因为如果我添加 A
和 D
的新子类,它将迫使我更新代码中的所有位置的列表。
使用
TypeVar
中的 typing
创建可以是任何类型的变量:
from typing import TypeVar
T = TypeVar('T', bound='A')
class A:
def f(self):pass
class D:
def g(self):pass
class B(A): pass
class C(A): pass
class E(B, D): pass
class F(C, D): pass
def h(obj: T):
pass
在上面的例子中,
T
可以是任何类型,但它被限制为A
和
D
的子类。
h
可以接受属于 A
和
D
的子类的任何对象。