Mike Bourbeau Mike Bourbeau - 2 months ago 16
Python Question

Python- Multiple dynamic inheritance

I'm having trouble with getting multiple dynamic inheritance to work. These examples make the most sense to me(here and here), but there's not enough code in one example for me to really understand what's going on and the other example doesn't seem to be working when I change it around for my needs (code below).

I'm creating a universal tool that works with multiple software packages. In one software, I need to inherit from 2 classes: 1 software specific API mixin, and 1 PySide class. In another software I only need to inherit from the 1 PySide class.

The least elegant solution that I can think of is to just create 2 separate classes (with all of the same methods) and call either one based on the software that's running. I have a feeling there's a better solution.

Here's what I'm working with:

## 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)


I'm currently getting this error:

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


Thanks for any help!

EDIT:



## 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()

Answer

The error in your original code is caused by failing to use tuple expansion in the class definition. I would suggest simplifying your code to this:

# 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)