簡體   English   中英

Python-多重動態繼承

[英]Python- Multiple dynamic inheritance

我在使多個動態繼承起作用時遇到了麻煩。 這些示例對我來說( 在這里此處 )最有意義,但是在一個示例中沒有足夠的代碼讓我真正了解正在發生的事情,而當我根據需要進行更改時,另一個示例似乎不起作用(下面的代碼)。

我正在創建可與多個軟件包一起使用的通用工具。 在一種軟件中,我需要繼承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()

原始代碼中的錯誤是由於未能在類定義中使用元組擴展引起的。 我建議將您的代碼簡化為:

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM