问题描述
我想弄清楚在 Python 中处理多重继承时,为什么不将具体子类视为抽象子类的子类。
请参阅下面的代码片段。
from abc import ABC
class AbstractFirstParent(ABC):
pass
class AbstractSecondParent(ABC):
pass
class AbstractChild(AbstractFirstParent,AbstractSecondParent):
pass
class ConcreteFirstParent(AbstractFirstParent):
pass
class ConcreteSecondParent(AbstractSecondParent):
pass
class ConcreteChild(ConcreteFirstParent,ConcreteSecondParent):
pass
print(issubclass(ConcreteChild,AbstractChild))
输出是 False
,但是我希望如果 ConcreteChild
继承自 ConcreteFirstParent
和 ConcreteSecondParent
,那么它继承自 AbstractFirstParent
和 {{1 }}。
因此,它必须从 AbstractSecondParent
继承,但由于某种原因它没有。
例如
AbstractChild
给出 print(
issubclass(ConcreteChild,AbstractFirstParent)
and issubclass(ConcreteChild,AbstractSecondParent)
)
,这是预期的。
谁能解释为什么 True
不被视为 ConcreteChild
的子类?
先谢谢你!
这是层次结构的直观表示。
AbstractChild
我问的原因与系统类型检查的实现有关,其中各种混合类用于组成一个具体的类。
在我看来,如果 AFP ASP
| \ / |
| \ / |
| \ / |
| AC |
CFP CSP
\ /
\ /
\ /
\ /
CC
继承自两个抽象父对象,就像 ConcreteChild
一样,那么它应该继承自后者。
现在我看到 CC 和 AC 之间没有直接联系,这就是为什么 AbstractChild
不被视为 ConcreteChild
的子类的原因。
但不清楚在这种情况下如何处理类型检查。
让我们说,一个函数返回一个 AbstractChild
实例,而根据不同的具体父级可能有各种类型的 ConcreteChild
。
所有的父项都基于 ConcreteChild
和 AbstractFirstParent
。
我希望函数返回值的类型是 AbstractSecondParent
,因为它继承自两个抽象父项。
我们能否以某种方式篡改 AbstractChild
以使其有效?
回答
这种方法,使用虚拟继承会有所帮助。
__subclasscheck__
在这种情况下,它按预期工作。
class ChildMeta(type):
def __subclasscheck__(cls,sub):
return (
issubclass(sub,AbstractFirstParent)
and issubclass(sub,AbstractSecondParent)
)
class AbstractChild(Metaclass=ChildMeta):
pass
根据需要给予。
print(issubclass(ConcreteChild,AbstractChild))
print(issubclass(ConcreteFirstParent,ConcreteChild))
解决方法
ConcreteFirstParent
、ConcreteSecondParent
和 AbstractChild
在当前代码中就像兄弟一样。 ConcreteChild
从 ConcreteFirstParent
和 ConcreteSecondParent
继承,即它不从 AbstractChild
继承任何东西。所以 ConcreteChild
确实不是 AbstractChild
的子类。
(不完全准确)家谱草图:
AFP ASP
/ | \
CFP CSP AC
|
CC