简体   繁体   English

python动态多重继承__init__

[英]python dynamic multiple inheritance __init__

I am trying to write a plugin environment where I need to do multiple inheritances on an unknown number of classes. 我正在尝试编写一个插件环境,在该环境中我需要在未知数量的类上进行多个继承。 Therefore, I have opted to use the type class creation: 因此,我选择使用类型类创建:

class A(object):
   def __init__(self,s):
      self.a="a"
   def testA(self,x):
      print(x)

class B(object):
   def __init__(self,s):
      self.b="b"
   def testA(self,x):
      print(x)

C = type('C', (A,B), {})

x= C("test")
print x.b

When I run the above code, I get the error: 当我运行上面的代码时,出现错误:

AttributeError: 'C' object has no attribute 'b'

This is because only the init for class A is being run when the instance for class C is initialized. 这是因为当C类的初始化实例只用于A类初始化正在运行。 My question is how can I get the class C to have both the init for class A as well as the init for class B to run when an instance of class C is initialized. 我的问题是如何获得C级同时具有A类初始化以及初始化为B类时,C类的一个实例初始化运行。 I do realize that if I had class C like the following it would work: 我的确意识到,如果我有如下的C类,它将可以工作:

class C(A,B):
    def __init__(self,s):
       A.__init__(self,s)
       B.__init__(self,s)

However, given that I need to have a dynamic list of classes inherited this will not work. 但是,鉴于我需要动态继承的类列表,因此将无法正常工作。

It seems you're using python 2 so I'm using this old python 2 super() syntax where you have to specify the class and the instance, although it would work in python 3 as well. 似乎您正在使用python 2,所以我使用的是旧的python 2 super()语法,尽管其中也可以在python 3中使用,但您必须在其中指定类和实例。 In python 3 you could also use the shorter super() form without parameters. 在python 3中,您也可以使用较短的super()形式而不使用参数。

For multiple inheritance to work is important that the grandparent class __init__ signature matches the signature of all siblings for that method. 要使多重继承有效,祖父母类__init__签名必须与该方法的所有同级的签名匹配。 To do that, define a common parent class ( MyParent in this example) whose __init__ has the same parameter list as all the childs. 为此,请定义一个公共父类(在本示例中为MyParent ,该父类的__init__具有与所有MyParent相同的参数列表。 It will take care of calling the object 's __init__ that doesn't take any parameter, for us. 对于我们来说,它将负责调用不带任何参数的__init__ object

from __future__ import print_function

class MyParent(object):
    def __init__(self, s):
        super(MyParent, self).__init__()

class A(MyParent):
    def __init__(self, s):
        self.a = "a"
        super(A, self).__init__(s)
    def testA(self, x):
        print(x)

class B(MyParent):
    def __init__(self, s):
        self.b = "b"
        super(B, self).__init__(s)

    def testA(self,x):
        print(x)

C = type('C', (A, B), {})

x = C("test")
print(x.b)

You can define as many children to MyParent as you want, and then all __init__ methods will be called, provided you used super() correctly. 您可以根据需要为MyParent定义尽可能多的子MyParent ,然后只要正确使用了super() ,就会调用所有__init__方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM