为何在父类构造函数中调用print(self)会引发RuntimeError?
PySide6多重继承中父类构造函数调用
print(self)触发RuntimeError的原因 错误回溯信息
Traceback (most recent call last): File "/home/neon/pyqt6/myqt/src/app.py", line 13, in <module> window = AppWindow() ^^^^^^^^^^^ File "/home/neon/pyqt6/myqt/src/app.py", line 7, in __init__ super(AppWindow, self).__init__() File "/home/neon/pyqt6/myqt/src/ui_mainwindow.py", line 5, in __init__ print(self) RuntimeError: '__init__' method of object's base class (AppWindow) not called.
复现步骤
- 在虚拟环境中安装
PySide6模块:pip install PySide6 - 创建
ui_mainwindow.py文件:from PySide6.QtWidgets import QLineEdit class Ui_MainWindow(object): def __init__(self): # 此调用引发错误 print(self) # 示例控件,与错误无关 def makeui(self): self.line_edit = QLineEdit() - 创建
app.py文件:from PySide6.QtWidgets import QMainWindow, QApplication from ui_mainwindow import Ui_MainWindow import sys class AppWindow(QMainWindow, Ui_MainWindow): def __init__(self): super(AppWindow, self).__init__() self.makeui() self.setCentralWidget(self.line_edit) if __name__ == "__main__": app = QApplication(sys.argv) window = AppWindow() window.show() app.exec() - 执行命令触发错误:
python app.py
纯Python环境下的正常表现
对比测试中,纯Python多重继承场景下,父类构造函数调用print(self)无异常:
main.py内容:from class_d import D class A(object): def __init__(self): super().__init__() class B(A): def __init__(self): super().__init__() class C(B): def __init__(self): super().__init__() class E(C, D): def __init__(self): super(E, self).__init__() e = E()class_d.py内容:class D(object): def __init__(self): print(self) # 此调用正常工作
执行python main.py可正常打印E对象的repr。
原因分析
这个错误的核心是Qt的C++对象模型与Python多重继承的初始化逻辑冲突:
- Qt的C++包装类(如
QMainWindow)的初始化有严格顺序要求,必须完成基类(如QWidget、QObject)的初始化后,才能安全访问对象的内部状态。 - 在你的代码中,
Ui_MainWindow的__init__在QMainWindow完成初始化前被执行(可能是super触发的MRO调用链中,Qt类的构造函数意外传递调用到Ui_MainWindow),此时调用print(self)会触发Qt对象的__repr__/__str__方法,这些方法依赖未初始化的C++内部状态,导致Qt抛出初始化未完成的错误。 - 纯Python环境无此问题,因为Python对象的
print(self)仅访问Python层面的属性,没有C++层面的初始化检查;而替换成print(self.__class__.mro())或字符串打印时,未触发Qt对象的内部状态访问,因此不会报错。
解决方法
- 显式调用所有基类构造函数:避免依赖
super的自动调用链,确保Qt类先完成初始化:class AppWindow(QMainWindow, Ui_MainWindow): def __init__(self): QMainWindow.__init__(self) # 先初始化Qt基类 Ui_MainWindow.__init__(self) # 再执行自定义类的初始化 self.makeui() self.setCentralWidget(self.line_edit) - 调整初始化逻辑:将
Ui_MainWindow中的初始化代码移到独立方法(如setupUi),在Qt类初始化完成后再调用,避免在__init__中操作Qt对象实例。
内容的提问来源于stack exchange,提问作者user47
相关产品推荐
相关产品推荐

