You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在父类构造函数中调用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.

复现步骤

  1. 在虚拟环境中安装PySide6模块:
    pip install PySide6
    
  2. 创建ui_mainwindow.py文件:
    from PySide6.QtWidgets import QLineEdit
    
    class Ui_MainWindow(object):
        def __init__(self):
            # 此调用引发错误
            print(self)
            
        # 示例控件,与错误无关
        def makeui(self):
            self.line_edit = QLineEdit()
    
  3. 创建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()
    
  4. 执行命令触发错误:
    python app.py
    

纯Python环境下的正常表现

对比测试中,纯Python多重继承场景下,父类构造函数调用print(self)无异常:

  1. 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()
    
  2. class_d.py内容:
    class D(object):
        def __init__(self):
            print(self)  # 此调用正常工作
    

执行python main.py可正常打印E对象的repr。

原因分析

这个错误的核心是Qt的C++对象模型与Python多重继承的初始化逻辑冲突:

  1. Qt的C++包装类(如QMainWindow)的初始化有严格顺序要求,必须完成基类(如QWidget、QObject)的初始化后,才能安全访问对象的内部状态。
  2. 在你的代码中,Ui_MainWindow的__init__在QMainWindow完成初始化前被执行(可能是super触发的MRO调用链中,Qt类的构造函数意外传递调用到Ui_MainWindow),此时调用print(self)会触发Qt对象的__repr__/__str__方法,这些方法依赖未初始化的C++内部状态,导致Qt抛出初始化未完成的错误。
  3. 纯Python环境无此问题,因为Python对象的print(self)仅访问Python层面的属性,没有C++层面的初始化检查;而替换成print(self.__class__.mro())或字符串打印时,未触发Qt对象的内部状态访问,因此不会报错。

解决方法

  1. 显式调用所有基类构造函数:避免依赖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)
    
  2. 调整初始化逻辑:将Ui_MainWindow中的初始化代码移到独立方法(如setupUi),在Qt类初始化完成后再调用,避免在__init__中操作Qt对象实例。

内容的提问来源于stack exchange,提问作者user47

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 03:32:16