在python的子类中有选择地继承

时间:2019-05-07 11:42:27

标签: python python-2.7 class inheritance multiple-inheritance

我定义了以下类:

$(document).ready(function () {

var newParent = document.getElementById('custom-map-controls');
        var oldParent = document.getElementsByClassName("leaflet-top leaflet-right")

        while (oldParent[0].childNodes.length > 0) {
            newParent.appendChild(oldParent[0].childNodes[0]);
        }
 });

哪个给出输出:

class First(object):
    def __init__(self):
        print("first")

    def mF1(self):
        print "first 1"

    def mF2(self):
        print "first 2"


class Second(object):
    def __init__(self):
        print("second")

    def mS1(self):
        print "second 1"


class Third(object):
    def __init__(self):
        print("third")

    def mT1(self):
        print "third 1"

    def mT2(self):
        print "third 2"

    def mT3(self):
        print "third 3"


class Fourth(First, Second, Third):
    def __init__(self):
        super(Fourth, self).__init__()
        print("fourth")


C = Fourth()
C.mF1()
C.mF2()
C.mS1()
C.mT1()
C.mT2()
C.mT3()

有了这个,很明显,类{{1}中的类first fourth first 1 first 2 second 1 third 1 third 2 third 3 FirstSecondThird的所有属性和方法都可用}。 现在,我希望类Fourth根据上下文有选择地从父级继承,即从Fourth单独继承,或者从FourthFirst等继承。一种方法是单独的类定义如下:

First

这意味着定义了单独的类,并使用单独的类名而不是一个。

我想知道是否有更简单,动态和“ pythonic”的方法来实现这一目标?是否可以通过简单的方式(例如

)选择从何处继承(就像Third一样,继承所有属性和方法,包括私有方法)
class Fourth1(First):
    def __init__(self):
        super(Fourth, self).__init__()
        print("fourth first")


class Fourth2(First, Third):
    def __init__(self):
        super(Fourth, self).__init__()
        print("fourth first third")

super()

继承
C = Fourth(1,0,0)

要从FirstC = Fourth(1,0,1) 继承?

1 个答案:

答案 0 :(得分:1)

可以通过__new__完成。因为可以动态创建从其他类继承的类,并且__new__可以创建任意类型的对象:

class Fourth(object):
    """BEWARE special class that creates objects of subclasses"""
    classes = [None] * 8

    def __new__(cls, first, second, third):
        index = 1 if first else 0
        index += 2 if second else 0
        index += 4 if third else 0
        if not cls.classes[index]:
            parents = [Fourth]
            if first: parents.append(First)
            if second: parents.append(Second)
            if third: parents.append(Third)
            ns = {'__new__': object.__new__,
                  '__init__': Fourth._child__init__,
                  '__doc__': Fourth.__doc__}
            cls.classes[index] = type('Fourth', tuple(parents), ns)
        return object.__new__(cls.classes[index])

    def _child__init__(self, first = None, second=None, third=None):
        Fourth.__init__(self)

    def __init__(self):
        print("Fourth")

之后,您可以做您想做的事情:

>>> c = Fourth(1,0,0)
Fourth
>>> c2 = Fourth(1,1,1)
Fourth
>>> c
<__main__.Fourth1 object at 0x0000024026151780>
>>> c2
<__main__.Fourth7 object at 0x000002402616E8D0>
>>> c2.mT1()
third 1
>>> c.mT1()
Traceback (most recent call last):
  File "<pyshell#302>", line 1, in <module>
    c.mT1()
AttributeError: 'Fourth1' object has no attribute 'mT1'

但是,除非您有重要的理由,否则我强烈建议您不要进行这种黑客攻击。因为它的结尾是一个类(Fourth),该类不是根据自身而是根据子类创建对象。显然属于该类的对象将具有不同的行为。这会打扰未来的读者和维护者