PYTHON

Python property(): Syntax, Usage, and Examples

The property() built-in function in Python lets you manage how class attributes are accessed and modified. Instead of calling explicit getter method or setter method, you can create attributes that behave like regular variables but include custom logic behind the scenes.

This gives your code clarity without losing control, making it essential for object-oriented programming (OOP) and a core concept that programmers working in Python programming must understand.

The property object created by this built-in function provides sophisticated attribute access control through encapsulation, a fundamental principle of OOP.

Quick Answer: What are Properties in Python?

A Python property is a special kind of attribute that lets you run code whenever it is accessed, set, or deleted. It allows you to expose what looks like a simple attribute to the user, while hiding the internal logic for getting or setting its value (getters and setters). This is most commonly done using the @property decorator.

Syntax & Example:

class Temperature:
    def __init__(self, celsius):
        # Internal, "private" variable
        self._celsius = celsius

    # 1. Define the "getter" with @property
    @property
    def temp(self):
        print("Getting temperature...")
        return self._celsius

    # 2. Define the "setter" with @temp.setter
    @temp.setter
    def temp(self, value):
        if value < -273.15:
            raise ValueError("Temperature below absolute zero is not possible.")
        print("Setting temperature...")
        self._celsius = value

# Usage
t = Temperature(25)
current_temp = t.temp # Accesses the getter
# Outputs: Getting temperature...
print(current_temp)
# Outputs: 25

t.temp = 30 # Accesses the setter
# Outputs: Setting temperature...

Properties allow you to add validation, transformations, or calculations to your attributes while keeping the class interface clean and simple.

How to Use the Python property() Function

You can create a property using either the property() function or the @property decorator. Both approaches create descriptors that control attribute access.

Syntax Using the property() Function

class Example:
    def __init__(self):
        self._value = 0# private attribute with underscore

    def get_value(self):
        """Getter method to retrieve attribute value"""
        return self._value

    def set_value(self, new_value):
        """Setter method to modify attribute value"""
        self._value = new_value

    def del_value(self):
        """Deleter method to remove attribute value"""
        del self._value

# property(fget, fset, fdel, doc)
    value = property(get_value, set_value, del_value, "Value property with getter, setter, and deleter")

This defines a value object attribute with custom getter method, setter, and deleter method. The property() call uses fget, fset, and fdel parameters to tie them together, along with a docstring in the doc parameter.

Syntax Using Python Decorators

class Example:
    def __init__(self):
        self._value = 0# private attribute using underscore convention

    @property
    def value(self):
        """Docstring for the property getter"""
        return self._value

    @value.setter
    def value(self, new_value):
        """Setter for the value property"""
        self._value = new_value

    @value.deleter
    def value(self):
        """Deleter for the value property"""
        del self._value

This approach using Python decorators is more common in modern Python programming and easier to read. The deleter decorator allows you to define what happens when del is called on the property.

When to Use property() in Python

Use the Python property function when you want to implement encapsulation in object-oriented programming:

  • Want to control attribute access to a Python class attribute without changing how it's used.
  • Need to run logic when an attribute value is read or updated.
  • Prefer cleaner syntax over calling getter method/setter methods.
  • Want to validate or transform values before storing them.
  • Need to convert a public attribute to a private attribute with controlled access.

These cases are common in applications that rely on clean interfaces or enforce strict rules for internal state, especially when working with instance attribute management.

Examples of Python Property in Action

Simple Getter and Setter

class Person:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, new_name):
        if not new_name:
            raise ValueError("Name cannot be empty")
        self._name = new_name

user = Person("Maya")
print(user.name)  # Output: Maya
user.name = "Sam"

This pattern lets you treat name like a variable, but with validation baked in.

Read-Only Property

class Temperature:
    def __init__(self, celsius):
        self._celsius = celsius

    @property
    def fahrenheit(self):
        return self._celsius * 9/5 + 32

t = Temperature(0)
print(t.fahrenheit)  # Output: 32.0

You get a derived value as a regular attribute without exposing a setter.

Write-Only Property

class PasswordManager:
    def __init__(self):
        self._hashed_password = None

    @property
    def password(self):
        raise AttributeError("Password is write-only")

    @password.setter
    def password(self, plain_text):
        self._hashed_password = hash(plain_text)

manager = PasswordManager()
manager.password = "mysecret"

This is useful when storing sensitive data like passwords.

Learn More About Python Properties

property() vs property decorator

Both property() and @property achieve the same goal. The decorator syntax is preferred for readability. The manual property() function is useful when you're defining multiple properties dynamically or want more control.

# Using property()
class Demo:
    def __init__(self):
        self._value = 0
    def get_value(self):
        return self._value
    def set_value(self, val):
        self._value = val
    value = property(get_value, set_value)

Python Property Setter and Getter Naming

Keep getter/setter method names consistent. Using the same name across the property, getter, and setter maintains clarity:

@property
def count(self):
    return self._count

@count.setter
def count(self, value):
    self._count = value

Avoid unrelated names like get_count() and modify_count() unless you’re using the property() function explicitly.

Cached Property in Python

You can improve performance with functools.cached_property. It caches the result of a method the first time it’s accessed:

from functools import cached_property

class Circle:
    def __init__(self, radius):
        self.radius = radius

    @cached_property
    def area(self):
        print("Calculating area...")
        return 3.14 * self.radius ** 2

c = Circle(5)
print(c.area)  # Calculates once
print(c.area)  # Uses cached result

This is useful for expensive calculations that don’t need to rerun unless the state changes.

Abstract Property in Python

You can define abstract properties in base classes using the abc module:

from abc import ABC, abstractmethod

class Animal(ABC):
    @property
    @abstractmethod
    def sound(self):
        pass

Subclasses must implement the sound property, ensuring a consistent interface.

Python Properties in Data Classes

With Python 3.8+, data classes can use properties too:

from dataclasses import dataclass

@dataclass
class Item:
    _price: float

    @property
    def price(self):
        return round(self._price, 2)

item = Item(12.3456)
print(item.price)  # Output: 12.35

This allows formatting, conversion, or validation on access.

Check If Property Exists in Python

To see if an attribute is a property, use:

isinstance(type(obj).__dict__["attr_name"], property)

Or, catch an AttributeError when accessing properties that aren't set.

Real-World Use Cases

Form Validation

When building forms, properties help you validate data before saving it:

class Form:
    def __init__(self):
        self._email = ""

    @property
    def email(self):
        return self._email

    @email.setter
    def email(self, value):
        if "@" not in value:
            raise ValueError("Invalid email")
        self._email = value

Data Transformation

Transform and store data behind the scenes without changing the public interface:

class Order:
    def __init__(self, amount):
        self._amount = amount

    @property
    def tax(self):
        return self._amount * 0.2

Simplify APIs

Libraries use properties to provide simpler interfaces without exposing internal methods.

Best Practices for Using Python Properties

  • Use properties for clean syntax, not just because you can.
  • Only add logic when you need to validate, transform, or compute on access.
  • Keep properties fast—don’t hide long computations behind them unless cached.
  • Combine with @classmethod or @staticmethod only when it makes sense.

The Python property function lets you create smart attributes that look like variables but act like functions. Whether you want to add validation, lazy calculations, or restrict access, properties give you the flexibility to keep your class interface clean and intuitive.

You can use the Python property decorator for readability, or stick with the base function if you're building classes dynamically. Either way, understanding properties in Python helps you write more maintainable, professional code.

Key Takeaways for Python Properties

  • Manages Attribute Access: The primary purpose of a property is to intercept attribute access (getting, setting, deleting) to run custom code, like validation or calculation.
  • @property is for Getters: The @property decorator turns a method into a "getter," which allows it to be accessed like an attribute (e.g., obj.my_prop) instead of a method (obj.my_prop()).
  • @<name>.setter is for Setters: To control what happens when a value is assigned to the property (e.g., obj.my_prop = 10), you must define a setter method using the @<name>.setter decorator.
  • Creates a Clean Interface: Properties allow you to maintain a simple public interface for your class attributes while keeping the internal implementation flexible and controlled.
  • Use a "Private" Variable: It is a strong convention to store the actual data in a "private" variable, typically prefixed with a single underscore (e.g., self._name), which the getter and setter methods then manage.
Learn to Code in Python for Free
Start learning now
button icon
To advance beyond this tutorial and learn Python by doing, try the interactive experience of Mimo. Whether you're starting from scratch or brushing up your coding skills, Mimo helps you take your coding journey above and beyond.

Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.

You can code, too.

© 2025 Mimo GmbH

Reach your coding goals faster