【问题标题】:Python 3.x: Avoid overwriting of same methods from different inherited classesPython 3.x:避免覆盖来自不同继承类的相同方法
【发布时间】:2018-04-14 12:39:38
【问题描述】:

我有以下问题:

我试图创建一个继承自其他两个类的类,这两个类各有内部__setitem__ 方法。作为featuresB 初始化的一部分,我想调用一个为该类创建内容的createFeaturesB 函数。不幸的是,__setitem__ 的调用指的是featuresA.__setitem__,从最后两个打印语句的输出可以看出。

class featuresA():
    def __init__(self):
        self._dictA      = dict()
        return
    def __setitem__(self, key, value):
        self._dictA[key] = value
        return

class featuresB():
    def __init__(self):
        self._dictB      = dict()
        self.createFeaturesB()
        return
    def __setitem__(self, key, value):
        self._dictB[key] = value
        return
    def createFeaturesB(self):
        for i in range(3):
            self[i] = i**2
        return

class C(featuresA, featuresB):
    def __init__(self):
        featuresA.__init__(self)
        featuresB.__init__(self)
        return

c = C()
print(c._dictB) #returns: {}
print(c._dictA) #returns: {0: 0, 1: 1, 2: 4}

如何避免这两种方法被覆盖?

【问题讨论】:

  • 你可以显式设置你想要的方法__setitem__ = featuresB.__setitem__,你可以切换父母的顺序,所以featuresB在MRO中排在第一位class C(featuresB, featuresA):,或者你不能从@987654330继承完全是@。
  • 谢谢。第一个解决方案是我目前要做的。

标签: python python-3.x multiple-inheritance


【解决方案1】:

有时最好先考虑是否正确构建了继承图。在这种情况下,颠倒继承顺序可以解决问题。

class C(featuresB, featuresA): # Reverse the inheritance order
    def __init__(self):
        featuresA.__init__(self)
        featuresB.__init__(self)

c = C()
c._dictB # {0: 0, 1: 1, 2: 4}
c._dictA # {}

虽然一般来说,从尚未实现支持它的类中进行多重继承是有问题的。您可能需要更新 featuresA 以使用 super

class featuresA():
    def __init__(self):
        self._dictA      = dict()
        super().__init__()

    def __setitem__(self, key, value):
        self._dictA[key] = value
        super().__setitem__(key, value)

class featuresB():
    def __init__(self):
        self._dictB      = dict()
        self.createFeaturesB()

    def __setitem__(self, key, value):
        self._dictB[key] = value

    def createFeaturesB(self):
        for i in range(3):
            self[i] = i**2

class C(featuresA, featuresB):
    def __init__(self):
        super().__init__()

c = C()
c._dictB # {0: 0, 1: 1, 2: 4}
c._dictA # {0: 0, 1: 1, 2: 4}

在更复杂的情况下,您希望从每个类中挑选某些方法,然后您需要重建您的类图,重写您的基类。多重继承是一个强大的工具,但它不是魔术。它将一些责任委托给开发者。

【讨论】:

  • 感谢您提供详细的概述!我很确定您的注释绝对正确……我仍然对我的类图不满意。 :/ 只要我还没有想出如何把它改成更好的东西,我会坚持使用凌乱的featuresB.__setitem__ 解决方案,尽管我对此并不满意。
猜你喜欢
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多