Python-多重动态继承

Python-多重动态继承,python,class,inheritance,dynamic,Python,Class,Inheritance,Dynamic,我很难让多个动态继承正常工作。这些例子对我来说是最有意义的(和),但是一个例子中没有足够的代码让我真正理解正在发生的事情,而另一个例子在我根据自己的需要进行更改时似乎不起作用(下面的代码) 我正在创建一个通用工具,可以与多个软件包一起使用。在一个软件中,我需要继承2个类:1个特定于软件的API mixin和1个PySide类。在另一个软件中,我只需要从1 PySide类继承 我能想到的最不优雅的解决方案是创建两个单独的类(使用所有相同的方法),然后根据正在运行的软件调用其中一个。我觉得有更好的解

我很难让多个动态继承正常工作。这些例子对我来说是最有意义的(和),但是一个例子中没有足够的代码让我真正理解正在发生的事情,而另一个例子在我根据自己的需要进行更改时似乎不起作用(下面的代码)

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

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

以下是我的工作内容:

## 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) # 
谢谢你的帮助

编辑:
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()
调用中。

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()
调用中。

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

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

上面的代码只适用于Python3,因此Python2似乎需要使用
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)

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

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

上面的代码只适用于Python3,因此Python2似乎需要使用
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)


这是因为它试图对
args
本身的元组进行子类化。如果您想要动态多重继承,请使用
type(name,base,dct)
。为了避免错误,您可以在使用*arg之前添加星号:class Build(*arg)。请注意,构造函数中对super的调用可能会根据作为arg传递的内容调用不同的东西,这是因为它试图对
args
本身的元组进行子类化。如果您想要动态多重继承,请使用
type(name,base,dct)
。为了避免错误,您可以在使用*arg之前添加星号:class Build(*arg)。请注意,构造函数中对super的调用可能会根据您作为arg传递的内容调用不同的内容。谢谢您的快速回复。我已经设置了脚本,但现在出现了以下错误:
#返回类型('Build',(BuildMixin,QtGui.QWidget)+args,{})
#类型错误:在Shiboken.ObjectType类型中使用了无效的基类。PySide只支持python新样式类的多重继承。我不确定这个类是如何“旧”样式的?请参阅我上面的帖子,了解我的代码using@MikeBourbeau:对不起,我不在;正如Ekhumaro指出的,
MayaQWidgetDockableMixin
是一个老式的类,您必须在这里的混合中添加
object
。感谢您的快速回复。我已经设置了脚本,但现在出现了以下错误:
#返回类型('Build',(BuildMixin,QtGui.QWidget)+args,{})
#类型错误:在Shiboken.ObjectType类型中使用了无效的基类。PySide只支持python新样式类的多重继承。我不确定这个类是如何“旧”样式的?请参阅我上面的帖子,了解我的代码using@MikeBourbeau:对不起,我不在;正如Ekhumaro指出的,
MayaQWidgetDockableMixin
是一个老式的类,您必须在这里的混合中添加
object
。谢谢您的回复,Ekhumaro!我在
类构建(*BaseClasses)的星号处发现一个语法错误:
。我的IDE中也有一个错误。即使直接复制和粘贴代码也会导致出现错误。我不熟悉这种扩展方法,但如果我能让它工作起来,它似乎是正确的方法。知道我为什么会犯这个错误吗?@MikeBourbeau。该死-看起来这在Python3中有效,但在Python2中不起作用(我想你一定在使用它)。是的,我是:/嗯,因为Maya 2017,我必须在某个时候移动到Python3。。。也许这是我开始的一天migrating@MikeBourbeau. 我添加了一个替代解决方案,它应该适用于Python2(我自己无法完全测试它)。该解决方案工作得非常好!非常感谢:谢谢你的答复