从两个元类派生时,\ uu init\ uuuuuuu中的类型错误

2024-09-28 03:22:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我想创建一个派生自PyQt5QtWidget.QWidgetabc.ABCMeta的类。这两个类都有自己的元类作为类型,因此,根据this pagethis SO question,我需要创建自己的元类,它派生自QWidgetabc.ABCMeta的元类,并显式地将其用作我的类的元类。你知道吗

到目前为止,我已经定义了一个QtAbcMeta类,并将其用作我的ConcreteWidget类的metaclass(见下文)。你知道吗

import abc
from PyQt5 import QtWidgets, QtCore


class AbstractClass(metaclass=abc.ABCMeta):

    def __init__(self, name):
        self._name = name

    @abc.abstractmethod
    def myMethod():
        pass


class QtAbcMeta(type(QtWidgets.QWidget), type(AbstractClass)):
    pass


class ConcreteWidget(QtWidgets.QWidget, AbstractClass, metaclass=QtAbcMeta):

    def __init__(self, name, parent=None):
        AbstractClass.__init__(self, name)
        QtWidgets.QWidget.__init__(self, parent=parent)  # This gives a type error.


    def myMethod():
        print("My widget does something")


def main():
    app = QtWidgets.QApplication([])
    myWidget = ConcreteWidget('my name', parent=None)

if __name__ == "__main__":
    main()

但是,当我尝试调用QtWidgets.QWidget方法的__init__方法来设置父级时,我得到以下TypeError:

Traceback (most recent call last):
  File "main.py", line 36, in <module>
    main()
  File "main.py", line 33, in main
    myWidget = ConcreteWidget('my name', parent=None)
  File "main.py", line 24, in __init__
    QtWidgets.QWidget.__init__(self, parent=parent)  # This gives a type error.
TypeError: __init__() missing 1 required positional argument: 'name'

我不知道这里怎么了。QtWidgets.QWidget.__init__的签名有什么变化吗?任何帮助都将不胜感激。你知道吗


Tags: nameselfinitmaindeftypemetaclassparent
1条回答
网友
1楼 · 发布于 2024-09-28 03:22:52

QT类被设计成以协作的方式在现代Python代码中使用,这意味着它们在内部使用Python的super(),以确保所有超类中的所有正确方法都用各自的参数调用。你知道吗

创建^{}完全是为了避免使用超类名硬编码对超类__init__(和其他重写方法)的调用,这样您就不必担心调用顺序。你知道吗

唯一的问题是,每个打算用作多类mixin的类都必须“知道”它是如何工作的,提取它使用的命名参数,并用剩余的参数再次调用super。 QT代码更进一步,检查其他类的所有命名参数是否都显示给它,否则它会出错。你知道吗

更重要的是,由于Qt类本身使用super,这意味着抽象类中的__init__将被调用两次。它在这个简单的代码中不会有什么不同,但在更复杂的基类中可能会有问题。你知道吗

因此,只需重写__init__方法,以“pythonic”的方式完成:

class ConcreteWidget(QtWidgets.QWidget, AbstractClass, metaclass=QtAbcMeta):

    def __init__(self, name, parent=None):
        super().__init__(name=name, parent=parent)

相关问题 更多 >

    热门问题