Python:使用装饰器更改 class 类型并保留其方法

Python: Change class type with decorator and keep it's methods

我想创建一个 class 可以在不同的应用程序及其 API 中使用它来创建 UI。为此,我创建了一个名为 ui.py 的模块。该模块内部有以下内容:

from PyQt4 import QtGui


def CreateGui(uiFile, parent=None):
    print "Ui build.."

def GetUiObject(uiClass):
    pUI = uiClass.PARENT
    class ParentUI(pUI):
        def __init__(self, uiFile):
            CreateGui(uiFile, self)
        def __call__(self, cls):
            for func in uiClass.__dict__:
                setattr(cls, func, uiClass.__dict__[func])
    return ParentUI

@GetUiObject
class UI(object):
    PARENT = QtGui.QMainWindow

    def __init__(self, uiFile):
        CreateGui(uiFile)

在应用程序使用的我的管道模块模块中:

from ui import UI

UI.PARENT = QtGui.QWidget

class Tool_UI(UI):
    def __init__(self, uiFile):
        super(Tool_UI, self).__init__(uiFile)
        print "In Application"


app = QtGui.QApplication(sys.argv)
A = Tool_UI("C:/test/testUi.ui")
A.CreateGui()

但我收到以下错误:

Ui build..
In Application
Traceback (most recent call last):
  File "C:/test/maxUi.py", line 13, in <module>
    A.CreateGui()
RuntimeError: super-class __init__() of type Tool_UI was never called

我做错了什么?

编辑:

cpburnz 回答了代码出错的原因,但仍然无法正常工作。 我想用另一个具有不同基础的 class 替换它。我打开了一个新问题,其中更好地描述了我的问题和我尝试过的不同解决方案 ()。

这看起来与 Python: RuntimeError: super-class __init__() of %S was never called 有关,但您的设置有点不同,所以我会推断以使其更清楚。

Traceback (most recent call last):
  File "C:/test/maxUi.py", line 13, in <module>
    A.CreateGui()
RuntimeError: super-class __init__() of type Tool_UI was never called

这意味着 Tool_UI 的 class 层次结构中的某处 super(...).__init__(...) 没有被调用。这似乎是由 QObjectQWidget 提出的。 查看GetUiObject()中定义的class,并没有调用super的init 即使父 class pUIQWidget。您很可能需要添加 在那里调用超级初始化:

def GetUiObject(uiClass):
    pUI = uiClass.PARENT

    class ParentUI(pUI):

        def __init__(self, uiFile):
            super(ParentUI, self).__init__() # <-- Missing.
            CreateGui(uiFile, self)

        def __call__(self, cls):
            for func in uiClass.__dict__:
                setattr(cls, func, uiClass.__dict__[func])

    return ParentUI