我无法使多个动态继承工作。这些例子对我来说是最有意义的(here和here),但是在一个例子中没有足够的代码让我真正理解发生了什么,另一个例子似乎没有起作用我根据自己的需要改变它(下面的代码)。
我正在创建一个适用于多个软件包的通用工具。在一个软件中,我需要继承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()
答案 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()
调用中。