Classes

Properties

@property keeps attribute syntax while adding computation or validation.

A read-only property exposes computed data through attribute access. area stays current because it is calculated from width and height each time it is read.

Source

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    @property
    def area(self):
        return self.width * self.height

    @property
    def width(self):
        return self._width

    @width.setter
    def width(self, value):
        if value <= 0:
            raise ValueError("width must be positive")
        self._width = value

box = Rectangle(3, 4)
print(box.area)

Output

12
obj.xfget / fset__dict__
When x is a property, attribute access routes through fget/fset instead of touching __dict__.

A setter lets assignment keep normal attribute syntax while the class validates or normalizes the value.

Source

box.width = 5
print(box.area)

Output

20

Validation belongs inside the class when every caller should obey the same rule. Invalid assignment raises an exception at the boundary.

Source

try:
    box.width = 0
except ValueError as error:
    print(error)

Output

width must be positive

Notes

See also

Run the complete example

Example code

Expected output

12
20
width must be positive

Execution time appears here after you run the example.