如何在python3.2中初始化所有继承的类?

时间:2014-10-28 21:56:53

标签: python oop python-3.x super

我正在使用python3.2,我有一个继承两个类的类。子类的子类__init__函数具有不同的签名。简而言之,是否可以创建一个调用每个子类的__init__的Parent对象?

背景

说我有以下python3.2代码

class A(object):
    def __init__(self, name):
        self.ver = "the ver"
        print("A::__init__ .... name = %s" % name)

class B(object):
    def __init__(self,):
        self.name = "the name"
        print("B::__init__")

    def foo(self,):
        print("B::foo.   The name is >>%s<<" % self.name)

class C(B,A):
    def  __init__(self,):
        print("C::__init__")
        super(B, self).__init__()
        super(A, self).__init__('waaa') 

我可以创建AB

的实例
>>> a = A('myplace')
A::__init__ .... name = myplace
>>> b = B()
B::__init__

但是,创建C的实例失败。

>>> c = C()
C::__init__
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "<console>", line 4, in __init__
TypeError: __init__() takes exactly 2 arguments (1 given)

如果我将__init__的{​​{1}}修改为

C

创建class C(B,A): def __init__(self,): print("C::__init__") super(B, self).__init__('another') super(A, self).__init__('waaa')

的实例时,我得到以下内容
C

我的问题

我阅读了super()的文件,目前尚不清楚是否可以拨打每个儿童班的>>> C() C::__init__ A::__init__ .... name = another Traceback (most recent call last): File "<console>", line 1, in <module> File "<console>", line 5, in __init__ TypeError: object.__init__() takes no parameters >>>

__init__实际上正在调用类super(B, self)__init__('another')的{​​{1}},而__init__正在调用类A的{​​{1}} 。

  1. 为什么super(A, self).__init__('waaa')不尊重它的__init__参数?
  2. 如何创建包含Bsuper()的所有类属性和方法的对象type

2 个答案:

答案 0 :(得分:1)

您错误地使用了super();它并不是要明确地调用特定的超级方法,而是要动态地在继承图中搜索下一个方法。 super()使用该类型查找从开始搜索的地点,跳过传入的类型。

在这种情况下,您只需直接调用父__init__

class C(B,A):
    def  __init__(self,):
      print("C::__init__")
      B.__init__(self)
      A.__init__(self, 'waaa') 

由于您的__init__方法具有特定签名,因此您不能只使用super();你的__init__方法需要符合一个签名(可以是一个接受任意参数并忽略它不需要的东西的那个)。

要明确,super()的第一个参数告诉它在搜索所请求的方法时跳过的类型,这就是你通常传入当前 class。

答案 1 :(得分:0)

  

为什么super()不尊重type这个论点?

因为super()没有使用type参数作为要使用的类型。相反,它根据MRO使用它来确定要使用的 next 类型。这就是你传递当前类型的原因。

  

如何创建具有A和B的所有类属性和方法的对象C?

AB正确使用super()。是的,它可以使构造函数的传递参数非常困难。不,没有好的解决方案,除了&#34;不要为构造函数签署不同的签名&#34;。