【问题标题】:Issubclass and multiple inheritanceIssubclass和多重继承
【发布时间】:2021-06-25 05:00:05
【问题描述】:

我想弄清楚在 Python 中处理多重继承时,为什么不将具体子类视为抽象子类的子类。

参见下面的代码 sn-p。


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 继承自ConcreteFirstParentConcreteSecondParent,那么它继承自AbstractFirstParentAbstractSecondParent。 因此,它必须继承自 AbstractChild,但由于某种原因它没有。

例如,

print(
    issubclass(ConcreteChild, AbstractFirstParent)
    and issubclass(ConcreteChild, AbstractSecondParent)
)

给出True,这是预期的。

谁能解释为什么ConcreteChild 不被视为AbstractChild 的子类?

提前谢谢你!

这是层次结构的可视化表示。

 AFP       ASP
 | \      / |
 |  \    /  |
 |   \  /   |
 |    AC    |
 CFP       CSP
  \        /
   \      /
    \    /
     \  /
      CC

我问的原因涉及系统类型检查的实现,其中各种 mixin 类用于组成一个具体的类。

在我看来,如果ConcreteChild 继承自两个抽象父级,就像AbstractChild,那么它应该继承自后者。

现在我看到 CC 和 AC 之间没有直接联系,这就是为什么 ConcreteChild 不被视为 AbstractChild 的子类的原因。 但目前尚不清楚在这种情况下如何处理类型检查。 比方说,一个函数返回一个ConcreteChild 实例,而基于各种具体的父级可能有各种ConcreteChild。 所有的父母都是基于AbstractFirstParentAbstractSecondParent。 我希望函数返回值的类型是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))

根据需要给予。

True
False

【问题讨论】:

  • AbstractChild 是它自己的类,而不是交集类型或“AbstractFirstParent 和 AbstractSecondParent”。作为 AbstractFirstParent 和 AbstractSecondParent 的子类不会使类成为 AbstractChild 的子类。

标签: python multiple-inheritance subclassing


【解决方案1】:

ConcreteFirstParentConcreteSecondParentAbstractChild 在当前代码中就像兄弟姐妹。 ConcreteChild 继承自 ConcreteFirstParentConcreteSecondParent,即它不继承自 AbstractChild 的任何内容。所以ConcreteChild确实不是AbstractChild的子类。

(不完全精确)家谱示意图:

   AFP   ASP
   /   |   \
CFP   CSP   AC
    |
   CC

【讨论】:

  • 感谢您的回复。我更新了问题和继承图。我想,你写的并不反映实际的层次结构。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-30
  • 2011-12-02
  • 2014-10-04
  • 2015-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多