看起来我偶然发现了一个元类地狱,即使我不想和它有任何关系。
我正在使用PySide在Qt4中编写一个应用程序。我想将事件驱动部分与UI定义分离,UI定义是由Qt设计器文件生成的。因此,我创建了一个“controller”类,但为了缓解我的生活,我无论如何都会多次继承它们。例如:
class BaseController(QObject):
def setupEvents(self, parent):
self.window = parent
class MainController(BaseController):
pass
class MainWindow(QMainWindow, Ui_MainWindow, MainController):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.setupEvents(self)
这和预期的一样。它还继承自(QDialog
,Ui_Dialog
,BaseController
)。但是,当我子类BaseController
并尝试从该子类继承(代替BaseController
)时,我收到一个错误:
TypeError: Error when calling the metaclass bases metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
澄清:QMainWindow
和QDialog
都继承自QObject
。BaseController
也必须从它继承,因为Qt事件系统的特性。Ui类只继承自简单的Python对象类。我寻找解决方案,但所有这些都涉及故意使用元类的情况。所以我一定是做错了什么。
编辑:通过添加图表,我的描述可能会更清晰。
工作示例:
QObject
| \___________________
| object |
QMainWindow | BaseController
| /---Ui_MainWindow |
| | MainController
MainWindow-----------------/
另一个工作示例:
QObject
| \___________________
| object |
QDialog | BaseController
| /---Ui_OtherWindow |
| | |
OtherWindow----------------/
不起作用的例子:
QObject
| \___________________
| object |
QDialog | BaseController
| /---Ui_OtherWindow |
| | OtherController
OtherWindow----------------/
我们用这样的东西:
假设良好的、现代的元类实现卫生(元类子类
type
,以及可以在__init__
中执行的任何操作都可以在那里完成)这允许许多元类相处。元类实际上也必须在
__new__
中完成大部分工作,无论如何都很难组合起来。通过确保其类是多重继承中的第一个元素,可以将其中一个元素偷偷带到这里。要使用它,您只需声明:
对于那些不同元类聚集在一起的类。
在这种情况下,例如:
对于不同的MetaA和MetaB,这比仅仅将它们继承在一起以关闭编译器要正确得多。
希望注释能解释代码。这里只有一个棘手的问题,那就是删除对从不同地方继承的任何给定
__metaclass__
的多余调用,并允许没有显式元类的类与其他类很好地配合。如果它看起来反应过度,您可以省略它,在您的代码中,只需仔细排序基类。这使得解决方案三行清晰明了。
错误消息表明您的层次结构中有两个相互冲突的元类。您需要检查每个类和QT类,以找出冲突的位置。
下面是一些设置相同情况的简单示例代码:
我们不能直接对这两个类进行子类划分,因为python不知道要使用哪个元类:
错误试图告诉我们的是,我们需要通过引入第三个元类来解决这两个元类之间的冲突,这个元类是基类中所有元类的子类。
我不确定这是否比错误消息本身更清楚,但基本上,您可以通过这样做来修复它:
这段代码现在可以正确编译和运行了。当然,在实际情况下,解决冲突的元类必须决定采用哪种父元类行为,您必须从应用程序的需求中自己找出这些行为。
请记住,继承的类只得到两个元类中的一个。
__init__
方法,这些方法有时会完成所有工作,因此在很多情况下,必须添加一个__init__
方法,以某种方式调用这两个类,以帮助它们相处。相关问题 更多 >
编程相关推荐