Python:使用decorator更改类类型并保留它的方法 [英] Python: Change class type with decorator and keep it's methods

查看:720
本文介绍了Python:使用decorator更改类类型并保留它的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 从PyQt4 import QtGui 


def CreateGui uiFile,parent = None):
printUi build ..

def GetUiObject(uiClass):
pUI = uiClass.PARENT
class ParentUI :
def __init __(self,uiFile):
CreateGui(uiFile,self)
def __call __(self,cls):
for func uiClass .__ dict__:
setattr(cls,func,uiClass .__ dict __ [func])
return ParentUI

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

def __init __(self,uiFile):
CreateGui(uiFile)

在我的管道模块模块内,由应用程序使用:

 从ui import UI 

UI.PARENT = QtGui.QWidget

class Tool_UI(UI):
def __init __(self,uiFile):
super(Tool_UI,self).__ init __(uiFile)
printIn Application


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

但我得到以下错误:

$ b $跟踪(最近最近一次调用):
文件C:/ test / bbbb:

  maxUi.py,第13行,在< module> 
A.CreateGui()
RuntimeError:类型Tool_UI的超类__init __()从未被调用


b $ b

我错了什么?



编辑: cpburnz 会解答为什么代码出错,但它仍然无法正常工作。
我想用另一个具有不同基础的类替换类。我打开一个新的问题,更好地描述我的问题和不同的解决方案,我试过(如何使用不同的基类对基类进行rebase或动态替换)。

解决方案

这看起来与 Python :RuntimeError:%S的超类__init __()从未被调用,但是你的设置有点不同,所以我将进行外推,使它更清楚。

  Traceback(最近一次调用):
文件C:/test/maxUi.py,第13行,在< module&
A.CreateGui()
RuntimeError:类型Tool_UI的超类__init __()从未被调用


b $ b

这意味着 Tool_UI 类类层次结构中 super(...).__ init __(...) code>
未被调用。这似乎是由 QObject QWidget 引发的。
看看在 GetUiObject()中定义的类,没有调用super的init
,即使父类 pUI QWidget 。您最可能需要添加
a调用到超级初始化:

  def GetUiObject(uiClass):
pUI = uiClass.PARENT

class ParentUI(pUI):

def __init __(self,uiFile):
super(ParentUI,self).__ init __() #< - 缺失。
CreateGui(uiFile,self)

def __call __(self,cls):
for func in uiClass .__ dict__:
setattr(cls,func,uiClass .__ dict__ [func])

return ParentUI


I want to create a class which could be used inside different Applications and their APIs to create UIs. Therefor I created a module called ui.py. Inside this module is the following:

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)

Inside my pipeline module module, which is used by the application:

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

But I get the following Error:

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

What do I wrong?

EDIT:

cpburnz answers why the code is erroring, but it is still not working. I want to replace the class with another one which has a different base. I opened a new question with a better description of my problem and different solutions I tried (How to rebase or dynamically replace a class with a different base class).

解决方案

This looks related to Python: RuntimeError: super-class __init__() of %S was never called but your setup is kind of different so I'll extrapolate to make it more clear.

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

This means somewhere in the class hierarchy for Tool_UI that super(...).__init__(...) is not being called. This appears to be raised by QObject or QWidget. Looking at the class defined in GetUiObject(), there is no call to the super's init even though the parent class pUI is QWidget. You most likely need to add a call to the super init there:

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

这篇关于Python:使用decorator更改类类型并保留它的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆