为什么属性装饰器显示“对象没有该属性”?

12 投票
2 回答
6516 浏览
提问于 2025-04-17 18:43

我有以下这段代码:

import sys
import platform
from PyQt4.QtGui import QApplication
from PyQt4.QtWebKit import QWebPage

class Render(QWebPage):
    def __init__(self):
        self.app = QApplication([])
        QWebPage.__init__(self)

    @property
    def html(self):
        return self.mainFrame().toHtml.toAscii()

page = Render()
print sys.version, platform.platform()
print 'html attribute?', [p for p in dir(page) if 'html' in p]
print page.html

运行后出现了这个错误信息:

stav@maia:$ python property.py
2.7.3 (default, Aug  1 2012, 05:14:39)
[GCC 4.6.3] Linux-3.2.0-38-generic-x86_64-with-Ubuntu-12.04-precise
html attribute? ['html']
Traceback (most recent call last):
  File "property.py", line 18, in <module>
    print page.html
AttributeError: 'Render' object has no attribute 'html'

如果我去掉 @property 这个装饰器,或者去掉 .toAscii 这个调用,代码就能正常运行了。但是为什么错误信息说没有这个属性,尽管用 dir(page) 查看时却能看到它呢?

2 个回答

2

你可能想说的是 .toHtml().toAscii()。注意这里缺少了括号。

18

这里的问题是,Python给出的错误信息让人感到有些误导。正常情况下,我们应该看到这样的错误信息:

AttributeError: 'function' object has no attribute 'toAscii'

但实际上,Python却给出了一个误导性的错误信息:

AttributeError: 'Render' object has no attribute 'html'

也就是说,一个在属性函数内部产生的AttributeError被呈现得像是这个属性本身的AttributeError

这种奇怪的情况发生在你的@property所在的类是从QObject派生出来的时候。这是PyQt中一个已知的问题。实际上,PyQt的维护者声称这是正常现象(我觉得这是错误的)。想了解更多细节,可以查看这个讨论串。(在那个讨论中,有人说QObject的行为和Python内置的object类是一样的,但我自己的测试结果却不一样。)

撰写回答