我试图创建一个既是抽象基类又继承了一个任意的 PySide6 类的类。然而,下面的代码会产生错误:TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
。
from abc import ABC, abstractmethod
from PySide6.QtWidgets import QApplication, QWidget
class MyBaseWidget(QWidget, ABC):
def __init__(self, parent=None):
super().__init__(parent=parent)
@abstractmethod
def foo(self):
pass
class MyConcreteWidget(MyBaseWidget):
def __init__(self, parent=None):
super().__init__(parent=parent)
app = QApplication([])
widget = MyConcreteWidget()
widget.show()
app.exec_()
我尝试使用以下解决方案来解决这个问题(灵感来自解决元类冲突、http://www.phyast.pitt.edu/~micheles/python/metatype.html、多重继承元类冲突等)。
class MyMeta(ABCMeta, type(QWidget)): pass
class MyBaseWidget(QWidget, metaclass=MyMeta):
def __init__(self, parent=None):
super().__init__(parent=parent)
@abstractmethod
def foo(self):
pass
class MyConcreteWidget(MyBaseWidget):
def __init__(self, parent=None):
super().__init__(parent=parent)
app = QApplication([])
widget = MyConcreteWidget()
widget.show()
app.exec_()
这段代码没有出现错误,但是我本来期望会出现一个错误,像这样的 TypeError: Can't instantiate abstract class MyConcreteWidget with abstract methods foo
当实例化 MyConcreteWidget
时。不能强制执行基类接口真的削弱了抽象基类的好处。有什么解决办法吗?
QWidget
类(QWidget
是任意的...它可以是任何 Qt 类),以便继承它的其他类必须实现该抽象方法(或方法)。这个问题不一定需要使用元类,但是ABCMeta
与QWidget
的元类冲突,所以我最初的想法是需要解决那个元类冲突。 - physhicsfoo
,这就是为什么在MyBaseWidget
中它是抽象的;没有foo
的默认实现。元类冲突是我尝试实现的副作用,因为 Python 的ABC
类与 Qt 类不兼容。 - physhics