【问题标题】:Python- Multiple dynamic inheritancePython-多重动态继承
【发布时间】:2017-02-14 04:32:37
【问题描述】:

我无法让多重动态继承工作。这些示例对我来说最有意义(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()

【问题讨论】:

  • 那是因为它试图继承 args 本身的元组。如果您想要动态多重继承,请使用type(name, bases, dct)
  • 为避免错误,您可以在使用时在 *arg 之前添加星号:class Build(*arg)。请注意,构造函数内部对 super 的调用可能会调用不同的东西,具体取决于您作为 arg 传递的内容。

标签: python class inheritance dynamic


【解决方案1】:

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

# 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() 的解决方案。从其他 cmets 看来,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)

【讨论】:

  • 感谢您的回复,ekhumoro!我在class Build(*BaseClasses): 的星号处收到语法错误。我的 IDE 也出现错误。即使直接复制和粘贴代码也会导致出现错误。我不熟悉这种扩展方法,但如果我能让它工作,它似乎是正确的选择。知道为什么我会收到此错误吗?
  • @MikeBourbeau。该死 - 看起来这在 Python 3 中有效,但在 Python 2 中无效(我假设您必须使用它)。
  • 是的,我是:/由于 Maya 2017,我必须在某个时候迁移到 Python 3...也许这是我开始迁移的那一天
  • @MikeBourbeau。我添加了一个应该适用于 Python 2 的替代解决方案(我自己无法完全测试它)。
  • 该解决方案完美运行!非常感谢:D
【解决方案2】:

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

【讨论】:

  • 感谢您的快速回复。我已经设置了我的脚本,但是我现在收到了这个错误:# return type('Build', (BuildMixin, QtGui.QWidget) + args, {})# TypeError: Invalid base class used in type Shiboken.ObjectType. PySide only support multiple inheritance from python new style class.我不确定这个类是如何“旧”风格的?请参阅我上面的帖子了解我正在使用的代码
  • @MikeBourbeau:对不起,我不在了;正如 ekhumoro 指出的那样,MayaQWidgetDockableMixin 是一个老式类,您必须在此处添加 object
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-19
  • 1970-01-01
  • 2020-12-18
  • 2021-08-05
  • 1970-01-01
相关资源
最近更新 更多