Python类不能从多个类继承,但有一个"选择"继承?

时间:2016-11-02 14:10:58

标签: python python-3.x oop inheritance

我目前正在使用3Rd派对应用。这个第三方应用已经定义了类:

 class VeryBaseClass(object):
      def __init__():
          pass

 class BaseClass(VeryBaseClass):
     def specific_method():
          pass

然后,饶恕论文:

 class Componenent[1,2,3,4....129883](BaseClass):
     def other_specific_method():
         pass

我无法修改这些类中的任何一个。所以,对于我来覆盖/补充方法,我只需要创建一个继承自Component的类,在那里我可以毫不费力地改变方法。

问题是,制作MyComponent1,然后是MyComponent2,MyComponent3等...所有用于复制粘贴类的内容中完全相同的代码,只是更改继承是非常烦人的,而不是DRY! / p>

那么,有没有办法创建这个类:

class MyComponentGeneric(Component1, Component2, Component3....):
      pass

MyComponentGeneric不会从列出的每个类继承,但可以从一个OR继承,具体取决于我的实例声明?

谢谢!

使用更具体的代码进行编辑

实际上,我已经尝试了每个答案中都有的东西,但我总是面临同样的错误:

我做了一个工厂,因为切普尼建议:

# This method is the one I use as a replacement
def newrender(self, name, value, attrs=None):
    result = super().render(name, value, attrs)
    if self.image is None:
        return result
    else:
        return '<img class="form-image" height="100" width="100" src="{}"/>'.format(self.image.url) + result


def MyWidgetFactory(widget, picture):
     newclass = type("WithImage" + widget.__name__, (widget,), dict(render=newrender))
     newclass.image = image
     return newclass()

但是一旦我的newrender方法启动,我就会收到这个错误:

result = super().render(name, value, attrs) RuntimeError: super(): __class__ cell not found

是因为工厂使用不当还是其他原因?

5分钟后编辑 好吧,我只需要通过super(type(self),self)调用超级单元格来填充它。不太确定它是如何工作的,但是,嘿,它有效!

谢谢大家!

3 个答案:

答案 0 :(得分:3)

这是字典的用例(如果字典键只是连续整数的序列,则可能是列表):

base_classes = {
    1: Component1,
    2: Component2,
    # ...
}

def ComponentFactory(comp_type):
    return base_classes(comp_type)()

在这里,ComponentFactory为您创建实例,而不是创建一个基本上只包装现有类而不实际添加它的新类。

如果确实需要新类型,您也可以在工厂中创建:

def ComponentFactory(comp_type):
    new_type = type('SomeTypeName', (base_classes[comp_type],), {})
    return new_type()

但是,您应该注意每个真实类只创建一个这样的包装器,这样您就不会得到一堆相同的单例类。

答案 1 :(得分:1)

如果不仔细查看代码库,很难回答。 但是,对我而言,看起来你可以用猴子修补来解决这个问题。

换句话说,您可以向Component1,Component2,Component3添加方法,甚至可以替换这些类的现有方法。

Remeamber python肯定是OOP,但它也提供了一套&#34;动态&#34;工具(例如猴子路径)你可以在很多场景中使用得很有效。

干杯

Chralie

答案 2 :(得分:1)

一,你不会命名你的类MyComponent2112,你有一个字典作为值。更容易使用。

然后只需在循环中创建类:

import third_party_module

mycomponents = dict()

for componentname in dir(third_party_module):
    if not componentname.startswith('Component'): continue
    baseclass = getattr(third_party_module, componentname)
    if not issubclass(baseclass, third_party_module.VeryBaseClass): continue
    number = int(componentname[9:])

    class MyComponent(baseclass):
        # Your updates here
    mycomponents[number] = MyComponent