Python-多动态继承

时间:2016-10-05 16:06:39

标签: python class inheritance dynamic

我无法使多个动态继承工作。这些例子对我来说是最有意义的(herehere),但是在一个例子中没有足够的代码让我真正理解发生了什么,另一个例子似乎没有起作用我根据自己的需要改变它(下面的代码)。

我正在创建一个适用于多个软件包的通用工具。在一个软件中,我需要继承2个类:1个特定于软件的API mixin和1个PySide类。在另一个软件中,我只需要从1 PySide类继承。

我能想到的最不优雅的解决方案是创建2个独立的类(使用所有相同的方法),并根据正在运行的软件调用其中一个。我觉得有更好的解决方案。

以下是我正在使用的内容:

## MainWindow.py

import os
from maya.app.general.mayaMixin import MayaQWidgetDockableMixin

# Build class
def build_main_window(*arg):

    class Build(arg):
        def __init__(self):
            super( Build, self ).__init__()

        # ----- a bunch of methods

# Get software
software = os.getenv('SOFTWARE')

# Run tool
if software == 'maya':
    build_main_window(maya_mixin_class, QtGui.QWidget)
if software == 'houdini':
    build_main_window(QtGui.QWidget)

我目前收到此错误:

#     class Build(arg):
# TypeError: Error when calling the metaclass bases
#     tuple() takes at most 1 argument (3 given) # 

感谢您的帮助!

编辑:

## MainWindow.py

import os

# Build class 
class BuildMixin():
    def __init__(self):
        super( BuildMixin, self ).__init__()

    # ----- a bunch of methods

def build_main_window(*args):
    return type('Build', (BuildMixin, QtGui.QWidget) + args, {})

# Get software
software = os.getenv('SOFTWARE')

# Run tool
if software == 'maya':
    from maya.app.general.mayaMixin import MayaQWidgetDockableMixin

    Build = build_main_window(MayaQWidgetDockableMixin)

if software == 'houdini':
    Build = build_main_window()

2 个答案:

答案 0 :(得分:2)

原始代码中的错误是由于未在类定义中使用元组扩展引起的。我建议将代码简化为:

# Get software
software = os.getenv('SOFTWARE')

BaseClasses = [QtGui.QWidget]
if software == 'maya':
    from maya.app.general.mayaMixin import MayaQWidgetDockableMixin
    BaseClasses.insert(0, MayaQWidgetDockableMixin)

class Build(*BaseClasses):
    def __init__(self, parent=None):
        super(Build, self).__init__(parent)

<强>更新

上面的代码只适用于Python 3,因此看起来Python 2需要使用type()的解决方案。从其他注释看来,MayaQWidgetDockableMixin类可能是一个旧式的类,所以这样的解决方案可能是必要的:

def BaseClass():
    bases = [QtGui.QWidget]
    if software == 'maya':
        from maya.app.general.mayaMixin import MayaQWidgetDockableMixin
        class Mixin(MayaQWidgetDockableMixin, object): pass
        bases.insert(0, Mixin)
    return type('BuildBase', tuple(bases), {})

class Build(BaseClass()):
    def __init__(self, parent=None):
        super(Build, self).__init__(parent)

答案 1 :(得分:1)

arg是一个元组,你不能使用元组作为基类。

使用type()代替创建新课程;它需要一个类名,一个基类元组(可以是空的)和类体(一个字典)。

我会以混合方式为你的班级保留方法:

class BuildMixin():
    def __init__(self):
        super(BuildMixin, self).__init__()

    # ----- a bunch of methods

def build_main_window(*arg):
    return type('Build', (BuildMixin, QtGui.QWidget) + args, {})

if software == 'maya':
    Build = build_main_window(maya_mixin_class)
if software == 'houdini':
    Build = build_main_window()

此处,args用作要继承的附加类。 BuildMixin类提供了所有实际方法,因此type()的第三个参数保留为空(生成的Build类具有空类主体)。

由于QtGui.QWidget在两个类之间很常见,我只是将其移到了type()调用中。