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) )
实际答案:在创建 die
s 之后将 uic.loadUi
调用移动到 。
代码评论:
- 只调用构造函数一次(不是一次
QMainWindow
和一次 super
)
- 使用
%s
时,您不需要同时调用 str()
-- 这就是 %s
的作用。
- 如果仅编写 Python3 代码,您的
super
调用可以省略 Dice, self
部分而只是 super().__init__(parent)
如评论中所述,出现错误是因为 loadUi
在 die1
之前调用了 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()
...
我不明白为什么以下代码在 __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) )
实际答案:在创建 die
s 之后将 uic.loadUi
调用移动到 。
代码评论:
- 只调用构造函数一次(不是一次
QMainWindow
和一次super
) - 使用
%s
时,您不需要同时调用str()
-- 这就是%s
的作用。 - 如果仅编写 Python3 代码,您的
super
调用可以省略Dice, self
部分而只是super().__init__(parent)
如评论中所述,出现错误是因为 loadUi
在 die1
之前调用了 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()
...