Python多重继承不显示类变量或第二个继承基类的方法

时间:2018-01-03 18:10:56

标签: python oop inheritance

你好的社区, 我正在学习OOPS概念,将python作为课程的一部分。我在python中遇到多重继承问题。以下是我的代码:

#!/usr/bin/env python

class Base1(object):
    def __init__(self):
        self.base1var = "this is base1"


class Base2(object):
    def __init__(self):
        self.base2var = "this is base2"

class MainClass(Base1, Base2):
    def __init__(self):
        super(MainClass, self).__init__()


if __name__ == "__main__":
    a = MainClass()
    print a.base1var
    print a.base2var

并且在运行时,我收到以下错误

print a.base2var
AttributeError: 'MainClass' object has no attribute 'base2var'

如果我交换继承的类的顺序,则错误中的变量名会相应地更改。

当我想调用两个继承类的构造函数时,我是否使用super()错误?

如何正确地继承多个基类并使用主类中的变量和方法而不会出现此错误?

谢谢。

5 个答案:

答案 0 :(得分:4)

您需要向Base1添加super调用,以便在Base1'之后调用Base2' __init__。您还可以向Base2添加super电话。没有必要,但它不会受到伤害。

class Base1(object):
    def __init__(self):
        super(Base1, self).__init__()
        self.base1var = "this is base1"

class Base2(object):
    def __init__(self):
        #super(Base2, self).__init__()
        self.base2var = "this is base2"

class MainClass(Base1, Base2):
    def __init__(self):
        super(MainClass, self).__init__()


if __name__ == "__main__":
    a = MainClass()
    print a.base1var
    print a.base2var

<强>输出

this is base1
this is base2
顺便说一句,你真的应该使用Python 3. super在现代Python中要好得多。 :)

答案 1 :(得分:3)

如果您使用super(),则必须始终使用 来确保调用所有类的方法。您的Base1Base2课程也应该使用super(...).__init__()方法调用__init__()。这将确保最终调用方法解析顺序中的所有类。

当并非所有__init__()方法都有一个空参数列表时,这确实有点棘手。在某些时候,super()将让您调用object.__init__(),并且永远不会接受任何参数。麻烦的是,您可能不知道这可能会提前发生在哪个类中。您可以通过创建object子类来解决这个问题,该子类在__init__()中接受任意数量的参数,并从中派生出来。该类不需要调用object.__init__(),因为该方法实际上没有做任何事情(或者,如果您可能会改变偏执,则可以在不使用object.__init__()的情况下调用super())。

通常,super()在参数处理中需要格外小心,因为您可能不知道方法解析顺序中的下一个类,因为您的代码的用户可能会使用您的基类组合使用新类没想到。因此,您需要做一些工作以确保所有类中的方法签名兼容。

有关更多信息,请参阅Raymond Hettinger的开创性Python's Super() Considered Super

答案 2 :(得分:2)

基本上发生的事情是Python正在查看父类(及其父母等,请参阅本段末尾的链接)以了解某些方法__init__。它从左到右读取类,因此它首先看到Base1。由于存在Base1.__init__,因此调用该方法。请在this answer阅读更详细的说明。

我认为调用所有适当方法的唯一方法是手动执行此操作

class MainClass(Base1, Base2):
    def __init__(self):
        Base1.__init__(self)
        Base2.__init__(self)

然后

a = MainClass()
print(a.base1var)
print(a.base2var)

打印

this is base1
this is base2

答案 3 :(得分:1)

Base1 __init__会覆盖Base2 __init__.py,因此永远不会创建base2var

您应该使用super,请参阅How does Python's super() work with multiple inheritance?

答案 4 :(得分:0)

使用超级而不是用于该目标并不是错误。解释super 我已经更改了你的代码

#!/usr/bin/env python

class Base1(object):
    def __init__(self):
        self.base1var = "this is base1"


class Base2(object):
    def __init__(self):
        self.base2var = "this is base2"

class MainClass(Base2, Base1):
    def __init__(self):
        super(MainClass, self).__init__()


if __name__ == "__main__":
    a = MainClass()
    print (a.base2var)

比你有

this is base2