Skip to content

property()

The built-in property() function lets you add managed attributes, also known as properties, to your custom classes. It allows you to define methods in a class that behave like attributes, enabling you to control access, mutation, and deletion of the underlying data without changing the class’s public API:

Language: Python Filename: circle.py
class Circle:
    def __init__(self, radius):
        self._radius = radius

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, value):
        self._radius = value

# Usage
circle = Circle(10)
print(f"Initial radius: {circle.radius}")
circle.radius = 20
print(f"Updated radius: {circle.radius}")

property() Signature

Language: Python Syntax
property(fget=None, fset=None, fdel=None, doc=None)

Arguments

Argument Description Default Value
fget A function object that returns the value of the managed attribute. None
fset A function object that sets the value of the managed attribute. None
fdel A function object that deletes the managed attribute. None
doc A string representing the property’s docstring. If omitted, the property copies the docstring of fget, if it has one. None

Return Value

  • A property object that allows controlled access and mutation of an instance attribute. The returned object exposes the fget, fset, and fdel constructor arguments as attributes, and, since Python 3.13, a __name__ attribute holding the property’s name.

property() Examples

With a direct call to property(), passing the getter and setter functions as arguments:

Language: Python Filename: temperature.py
class Temperature:
    def __init__(self, celsius):
        self._celsius = celsius

    def _get_celsius(self):
        return self._celsius

    def _set_celsius(self, value):
        self._celsius = float(value)

    celsius = property(_get_celsius, _set_celsius, doc="Degrees Celsius.")

# Usage
temp = Temperature(25)
print(temp.celsius)  # Output: 25
temp.celsius = 30
print(temp.celsius)  # Output: 30.0

The @property decorator is shorthand for this call. Decorating a radius() method with @property is equivalent to writing radius = property(radius), and @radius.setter returns a copy of the property with the setter added.

Calling property() directly is useful when you already have getter and setter functions, want to reuse them across several properties, or need to build properties dynamically.

With a read-only attribute:

Language: Python Filename: point.py
class Point:
    def __init__(self, x, y):
        self._x = x
        self._y = y

    @property
    def x(self):
        return self._x

    @property
    def y(self):
        return self._y

# Usage:
p = Point(3, 4)
print(p.x)  # Output: 3
print(p.y)  # Output: 4
p.x = 10  # This will raise an AttributeError

With a read-write attribute:

Language: Python
class Square:
    def __init__(self, side):
        self._side = side

    @property
    def side(self):
        return self._side

    @side.setter
    def side(self, value):
        self._side = value

# Usage
rectangle = Square(10)
print(rectangle.side)  # Output: 10
rectangle.side = 15
print(rectangle.side)  # Output: 15

property() Common Use Cases

The most common use cases for the property() function include the following:

  • Creating read-only, read-write, or write-only attributes
  • Validating input data for attributes
  • Computing attribute values dynamically
  • Logging attribute access and mutation
  • Maintaining backward-compatible public APIs

property() Real-World Example

Here’s an example where you use property() to manage a circle’s radius and diameter. Note that the radius is a user-provided attribute while the diameter is a computed attribute:

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

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, value):
        self._radius = float(value)

    @property
    def diameter(self):
        return self.radius * 2

    @diameter.setter
    def diameter(self, value):
        self.radius = value / 2

# Usage
circle = Circle(10)
print(circle.diameter)  # Output: 20.0
circle.diameter = 30
print(circle.radius)    # Output: 15.0

This example demonstrates how property() helps you manage related attributes without changing the public API of a class by turning attributes into methods.

Python's property(): Add Managed Attributes to Your Classes

Tutorial

Python's property(): Add Managed Attributes to Your Classes

In this tutorial, you'll learn how to create managed attributes in your classes using Python's property(). Managed attributes are attributes that have function-like behavior, which allows for performing actions during the attribute access and update.

intermediate best-practices python

For additional information on related topics, take a look at the following resources:

Have a question about this? Mentor AI can show you examples, compare related terms, and point you to tutorials.


By Leodanis Pozo Ramos • Updated Oct. 5, 2026 • Reviewed by Dan Bader