Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does property decorator show "object has no attribute"?

I have the following code:

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

gives this exception output:

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'

If I remove the @property decorator or I remove the .toAscii call, then it works. But why does the error say there is no attribute even tho dir(page) shows it?

like image 637
Steven Almeroth Avatar asked Mar 11 '13 20:03

Steven Almeroth


People also ask

What does the property decorator do?

The @property is a built-in decorator for the property() function in Python. It is used to give "special" functionality to certain methods to make them act as getters, setters, or deleters when we define properties in a class.

How do you print a property object in Python?

Use Python's vars() to Print an Object's Attributes The dir() function, as shown above, prints all of the attributes of a Python object.

How does @property work Python?

The property() method in Python provides an interface to instance attributes. It encapsulates instance attributes and provides a property, same as Java and C#. The property() method takes the get, set and delete methods as arguments and returns an object of the property class.

What is @property in Python class?

The @property Decorator In Python, property() is a built-in function that creates and returns a property object. The syntax of this function is: property(fget=None, fset=None, fdel=None, doc=None)


1 Answers

The issue here is that Python gave a misleading error message. The error message one would expect in this case is this:

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

But instead, Python gave a misleading error message:

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

That is, an AttributeError generated within the property function was presented as if it were an AttributeError for the property itself.

This strange behavior occurs when the class with your @property is derived from QObject. It is a known issue in PyQt. In fact, the PyQt maintainers claim it is expected behavior (wrongly, IMHO). See this thread for details. (In that thread, it is claimed that QObject behaves identically to Python's built-in object class, but my own testing indicates otherwise.)

like image 56
Stuart Berg Avatar answered Nov 12 '22 00:11

Stuart Berg