Back to Python Notes
Topic #236

Class Properties

Learn how to use the @property decorator in Python to define attributes that behave like data but execute code, enabling validation and computed values without breaking existing interfaces.

What it is

In many languages, you expose internal state via public fields or write explicit getter/setter methods. In Python, we prefer simple attributes (e.g., obj.x) for direct access. However, when you need logic—such as validation, calculation, or lazy loading—you can upgrade an attribute into a property using the @property decorator. A property allows you to define a method that looks and acts like an attribute. This maintains backward compatibility: code that reads obj.area does not need to change if area becomes a property later.

Related terms include descriptors (the underlying mechanism), getters, setters, and deleters.

Why it matters

  • Data Validation: Prevent invalid states by checking values during assignment.
  • Computed Attributes: Provide derived values (like area from width/height) without storing redundant data.
  • API Stability: Change internal implementation details without forcing clients to update their code.
  • Laziness: Calculate expensive results only when accessed.

Syntax or steps

To create a read-only property, decorate a method with @property. To make it writable, add a setter decorated with @name.setter. For deletion, use @name.deleter.

  1. Define the instance variables (usually private, prefixed with _).
  2. Create a method named after the desired attribute.
  3. Add the @property decorator above the method definition.
  4. (Optional) Add @method_name.setter to handle assignment.

Example

class Rectangle:
    def __init__(self, w, h):
        self._w = w
        self._h = h

    @property
    def area(self):
        """Compute area dynamically."""
        return self._w * self._h

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

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

# Usage
r = Rectangle(5, 10)
print(r.area)   # Output: 50 (acts like an attribute)
r.width = 8     # Triggers setter validation
print(r.area)   # Output: 80
try:
    r.width = -5 # Raises ValueError
except ValueError as e:
    print(e)

The area property calculates the result on every access. The width property uses a setter to ensure the value remains positive before updating the internal _w variable.

Common mistakes

  • Recursion in Setters: Assigning to the property name inside its own setter causes infinite recursion. Always assign to the underlying private variable (e.g., self._w = value, not self.w = value).
  • Forgetting the Underscore: If you don't prefix internal storage with _, you might accidentally overwrite the property descriptor itself.
  • Overusing Properties: Do not use properties for trivial getters that just return a stored value. Use them only when logic is required.
  • Performance Assumptions: Properties execute code on every access. Avoid heavy computations in frequently accessed properties unless caching is implemented.

When to use it

Approach Best For Trade-off
Simple Attribute Direct data storage with no logic. No validation or computation possible.
Method Call (get_area()) Explicit actions or complex calculations. Breaks "attribute-like" syntax; verbose.
Property (@property) Validation, computed values, API stability. Slight overhead; requires careful naming.

Practice

Guided Exercise: Create a Temperature class that stores Celsius internally. Add a property fahrenheit that converts and returns the value. Add a setter for fahrenheit that updates the internal Celsius value.

Challenge: Modify the Rectangle example to cache the area so it is only recalculated if width or height changes. Hint: Use a flag or compare current dimensions against cached ones.

Quick check

Q: Why do we typically store data in self._value instead of self.value when defining a property named value?
A: Storing in self.value would trigger the property's setter again, causing infinite recursion. Using self._value accesses the raw attribute directly.

Summary

Python properties allow you to attach logic to attribute access while maintaining clean syntax. They are essential for validating input, computing derived values, and evolving classes without breaking client code. Use them judiciously where behavior differs from simple data storage.

Want to go beyond the notes?

Join Coding Now Tech Institute's Python course — live mentorship, real projects, and 100% placement support.

Enroll Now — Free Demo Available

Class Properties – FAQs

Quick answers about learning Class Properties in Python.

This free note from Coding Now Tech Institute explains Class Properties in Python — concept, syntax and worked code examples you can copy, run and revise before interviews.
Yes. Every Python topic on Coding Now Tech Institute, including Class Properties, is 100% free with no signup required.
With focused practice, most students grasp Class Properties in 1–3 days from these notes; pairing it with Coding Now Tech Institute's mentor-led course takes you to job-ready depth faster.
Use the code examples in this note, then ask doubts for free on the Coding Now Tech Institute Community (/community) — expert instructors answer within 24 hours.
Call NowEnroll Now