Tim
Tim

Reputation: 99606

Is a property a class attribute or an instance attribute?

From Python in a Nutshell

A property is an instance attribute with special functionality. ...

Here’s one way to define a read- only property:

class Rectangle(object):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    def get_area(self):
        return self.width * self.height
    area = property(get_area, doc='area of the rectangle')

Each instance r of class Rectangle has a synthetic read-only attribute r.area , computed on the fly in method r.get_area() by multiplying the sides.

Is a property a class attribute or an instance attribute?

  1. Does the above quote imply that a property is an instance attribute?

  2. A property is always defined inside the definition of a class, so is a property a class attribute.

  3. Does Rectangle.__dict__ store the class attributes and an Rectangle instance's __dict__ store the instance attributes? If yes, then does the following show that the property is a class attribute instead of an instance attribute:

>>> Rectangle.__dict__    
mappingproxy({..., 'area': <property object at 0x7f34f7ee2818>})
>>> r=Rectangle(2,3)
>>> r.__dict__    {'width': 2, 'height': 3} 

Upvotes: 0

Views: 490

Answers (1)

jonrsharpe
jonrsharpe

Reputation: 122161

The property object itself is a class attribute, as its position inside the class body implies; you can still access class attributes on instances, though, just not vice versa.

What makes the property different is the descriptor protocol; in the case of accessing r.area, the following (roughly) happens:

  • Python looks for the attribute on the instance, and doesn't find it; then
  • Python looks for the attribute on the instance's type, and does find it; then
  • Python finds that the resulting value implements __get__, so;
  • Python invokes that method with the instance and the class.

What actually gets called is therefore:

Rectangle.area.__get__(r, Rectangle)

This is how the property descriptor accesses the instance's state while actually being an attribute on the class; the instance is passed into it. You can tell it's a class attribute because it's accessible on the class, without creating any instances:

>>> Rectangle.area
<property object at 0x...>

Upvotes: 2

Related Questions