Python 类属性未按预期显示
我不明白为什么下面的代码返回一个错误Python 类属性未按预期显示,python,python-3.x,pyqt5,Python,Python 3.x,Pyqt5,我不明白为什么下面的代码返回一个错误AttributeError:“Dice”对象在\uu str\uu方法中没有属性“die1”。我知道我已经创建了一个,我的调试器将其显示为类属性。这个(简单的)代码有什么问题 实际答案:创建dies后,将uic.loadUi调用移动到 对守则的评论: 只调用构造函数一次(不是作为QMainWindow调用一次,而是作为super调用一次) 使用%s时,您不需要同时调用str()——这就是%s所做的 如果只编写Python3代码,那么您的super调用可以省
AttributeError:“Dice”对象在\uu str\uu
方法中没有属性“die1”
。我知道我已经创建了一个,我的调试器将其显示为类属性。这个(简单的)代码有什么问题
实际答案:创建
die
s后,将uic.loadUi
调用移动到
对守则的评论:
- 只调用构造函数一次(不是作为
调用一次,而是作为QMainWindow
调用一次)super
- 使用
时,您不需要同时调用%s
——这就是str()
所做的%s
- 如果只编写Python3代码,那么您的
调用可以省略super
部分,而只是Dice,self
super()
loadUi
在设置die1
之前调用类实例(即self
)上的\uu str
uic
模块之所以这样做,是因为它在解析ui
文件时收集了大量调试信息,其中包括记录作为loadUi
的baseinstance
参数传递的对象
不幸的是,它通过(间接)调用\uuuu str\uuu
来实现这一点,而它可能应该调用\uuu repr\uu
。(或者可能只是在调用python API函数时根本不记录调试信息。命令行界面有一个打开调试的选项,但它似乎只控制是否显示记录的信息,而不是是否首先收集)
当然,在初始化过程中尽可能早地调用loadUi
,这是很自然的——就像您使用setupUi
一样。但无论您如何将ui加载到应用程序中,uic
都将以完全相同的方式生成代码。与loadUi
的唯一区别在于,它在运行时调用生成的代码,而对于pyuic
,相同的代码只是作为静态模块导入
有很多方法可以解决你眼前的问题。我个人认为我可能会选择预先初始化die1/die2
作为类属性:
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()
...
显然错误的是,您两次使用基类
\uuuu init\uuuu
(一次显式地使用super
——丢失其中一个!),但这并不能解释您观察到的错误。引发错误的原因是,loadUi
在类实例上调用\uuu str\uuuu
(您将其作为self
传递给它)在die1
被设置之前。感谢您指出双重承包商的电话,我自己也注意到了,睡了一夜!然而,Ekhumaro解决了这个问题!谢谢想进一步评论吗?我正在从PyQt4切换到PyQt5,并且总是在代码之外编译ui。我想我需要在设置信号之前加载ui,这是真的吗?还有,为什么loadUi会在我的类上调用str方法?如果您使用的是python 3x,那么您可以在不使用该类的情况下调用父方法超级()
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()
...