Class 属性未按预期显示

Class attribute not showing up as expected

我不明白为什么以下代码在 __str__ 方法中返回错误 AttributeError: 'Dice' object has no attribute 'die1'。我知道我已经创建了一个,我的调试器将它显示为 class 属性。这个(简单的)代码有什么问题?

   class Dice(QMainWindow) :
        """A game of Dice."""

        def __init__(self, parent = None):
            """Build a game with two dice."""

            QMainWindow.__init__(self, parent)

            super(Dice, self).__init__(parent)
            uic.loadUi("Dice.ui", self)

            self.die1 = Die()
            self.die2 = Die()
            self.rollButton.clicked.connect(self.rollButtonClickedHandler)


        def __str__( self ):
            """String representation for Dice.
            """
            return "Die1: %s\nDie2: %s" % ( str(self.die1),  str(self.die2) )

实际答案:在创建 dies 之后将 uic.loadUi 调用移动到

代码评论:

  • 只调用构造函数一次(不是一次 QMainWindow 和一次 super
  • 使用 %s 时,您不需要同时调用 str() -- 这就是 %s 的作用。
  • 如果仅编写 Python3 代码,您的 super 调用可以省略 Dice, self 部分而只是 super().__init__(parent)

如评论中所述,出现错误是因为 loadUidie1 之前调用了 class 实例(即 self)上的 __str__已设置。

uic 模块这样做的原因是因为它在解析 ui 文件时收集了大量调试信息,其中包括日志记录作为 loadUi.

baseinstance 参数传递的对象

不幸的是,它通过(间接)调用 __str__ 而它可能应该调用 __repr__ 来做到这一点。 (或者可能只是在调用 python API 函数时 根本 不记录调试信息。命令行界面有一个 切换选项on debugging,不过好像只控制了记录的信息是否显示,而不是一开始是否收集。

在初始化过程中尽早调用 loadUi 当然是很自然的——就像你调用 setupUi 一样。但无论您如何将 ui 加载到您的应用程序中,uic 都会以完全相同的方式生成代码。 loadUi 的唯一区别是它在运行时对生成的代码调用 exec(),而 pyuic 只是将相同的代码作为静态模块导入。

有多种方法可以解决您眼前的问题。就个人而言,我想我可能会选择将 die1/die2 预初始化为 class 属性:

   class Dice(QMainWindow) :
        """A game of Dice."""
        die1 = die2 = None

        def __init__(self, parent=None):
            """Build a game with two dice."""
            super().__init__(parent)
            uic.loadUi("Dice.ui", self)
            self.die1 = Die()
            self.die2 = Die()
            ...