How to Use @property Decorator in Python

I have spent over a decade building large-scale Python applications, and if there is one tool that separates clean, professional code from “just getting it done,” it is the @property decorator.

When I first started, I used to write Java-style getters and setters for everything, but Python offers a much more elegant way to handle data.

In this tutorial, I’ll show you exactly how to use the @property decorator to make your classes more “Pythonic” and robust.

What is the @property Decorator?

The @property decorator is a built-in feature in Python that allows you to define a method but access it like an attribute.

It is essentially a way to use getters and setters without changing the user interface of your class.

Method 1: Use @property for Basic Getters

The most common use case I encounter is wanting to protect an attribute or calculate a value on the fly. Instead of exposing a raw variable, you wrap it in a property.

Suppose we are building a payroll system for a company in New York. We want to ensure the employee ID is accessible but not directly modified by mistake.

class US_Employee:
    def __init__(self, emp_id, name):
        self._emp_id = emp_id  # Internal attribute
        self.name = name

    @property
    def emp_id(self):
        """The getter for employee ID."""
        return f"EMP-NY-{self._emp_id}"

# Usage
employee = US_Employee(1024, "John Doe")
print(employee.emp_id)  # Output: EMP-NY-1024

I executed the above example code and added the screenshot below.

@property Decorator in Python

In my experience, using this approach from the start saves you from huge refactoring headaches later when your logic needs to change.

Method 2: Add Validation with @property.setter

One of the biggest mistakes I see junior developers make is allowing invalid data to enter an object. With the .setter decorator, you can intercept the assignment and validate it.

Let’s look at a real estate example where we handle property taxes in Texas. We need to ensure the appraised value is never a negative number.

class TexasProperty:
    def __init__(self, address, value):
        self.address = address
        self.value = value # This calls the setter automatically

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, market_price):
        if market_price < 0:
            raise ValueError("The appraised value in Texas cannot be negative.")
        print(f"Setting value to: ${market_price:,}")
        self._value = market_price

# Usage
home = TexasProperty("123 Lone Star Lane, Austin", 450000)
home.value = 500000  # Updates correctly
# home.value = -100  # This would raise a ValueError

I executed the above example code and added the screenshot below.

Use @property Decorator in Python

I find this incredibly useful because it keeps your data integrity logic right where it belongs, inside the class definition.

Method 3: Use @property for Computed Attributes

Sometimes you don’t want to store a piece of data because it depends on other attributes.

In the USA, sales tax varies by state. We can use a property to calculate the total price including tax dynamically.

class CaliforniaOrder:
    def __init__(self, item_name, price):
        self.item_name = item_name
        self.price = price
        self.tax_rate = 0.0725  # CA Base Sales Tax

    @property
    def total_price(self):
        """Calculates total price on the fly."""
        return round(self.price * (1 + self.tax_rate), 2)

# Usage
order = CaliforniaOrder("MacBook Pro", 2000)
print(f"Total price in CA: ${order.total_price}")

I executed the above example code and added the screenshot below.

How to Use @property Decorator in Python

This prevents the “stale data” bug, where you update the price but forget to update the total.

Method 4: Clean Up with @property.deleter

The deleter is the least used part of the property decorator, but it’s vital when you need to perform cleanup.

For instance, if you are managing a cloud server instance in an AWS US-East region, you might want to log a message or clear a cache when an attribute is deleted.

class CloudServer:
    def __init__(self, instance_id):
        self._instance_id = instance_id

    @property
    def instance_id(self):
        return self._instance_id

    @instance_id.deleter
    def instance_id(self):
        print(f"Shutting down and clearing records for instance: {self._instance_id}")
        del self._instance_id

# Usage
aws_node = CloudServer("i-04f5e6a7b8c9d")
del aws_node.instance_id

I rarely use deleters in simple scripts, but in production-grade systems, they are great for resource management.

Why You Should Use @property Instead of Regular Methods

You might ask, “Why not just use get_value() and set_value()?”

In Python, we value readability. Using @property allows you to change your implementation without changing the API.

If you start with a simple attribute like self.price = 100 and later realize you need validation, you can switch to a @property without breaking any code that already uses obj.price.

This is what we call “graceful evolution” of code.

Common Issues to Avoid

Even with experience, I still see people trip up on these:

  1. Infinite Recursion: If your property name is the same as the internal variable (e.g., self.price = price inside the setter of price), Python will call the setter again and again until it crashes. Always use a leading underscore for the internal variable (e.g., self._price).
  2. Overusing Properties: Don’t turn every single method into a property. If a calculation is computationally expensive (like a database query), it should probably be a method so the user knows it has a cost.

Final Thoughts on Python Properties

Mastering the @property decorator was a turning point in my career. It allowed me to write classes that feel native to Python while maintaining strict control over the data.

You may also like to read:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.