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:
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
property(fget=None, fset=None, fdel=None, doc=None)
Note: It’s common to refer to property() as a built-in function. Technically, property is a class defining a descriptor type designed to be used as a function. That’s why most Python developers call it a function. In practice, property() is used as a decorator most of the time.
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
property() Examples
With a direct call to property(), passing the getter and setter functions as arguments:
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:
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:
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:
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.
Related Resources
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.
For additional information on related topics, take a look at the following resources:
- Getters and Setters: Manage Attributes in Python (Tutorial)
- Managing Attributes With Python's property() (Course)
- Python Descriptors: An Introduction (Tutorial)
- Object-Oriented Programming (OOP) in Python (Tutorial)
- Python Classes: The Power of Object-Oriented Programming (Tutorial)
- Python's property(): Add Managed Attributes to Your Classes (Quiz)
- Getters and Setters in Python (Course)
- Getters and Setters: Manage Attributes in Python (Quiz)
- Python Descriptors (Course)
- Python Descriptors: An Introduction (Quiz)
- A Conceptual Primer on OOP in Python (Course)
- Intro to Object-Oriented Programming (OOP) in Python (Course)
- Object-Oriented Programming (OOP) in Python (Quiz)
- Class Concepts: Object-Oriented Programming in Python (Course)
- Inheritance and Internals: Object-Oriented Programming in Python (Course)
- Python Classes - The Power of Object-Oriented Programming (Quiz)
Have a question about this? Mentor AI can show you examples, compare related terms, and point you to tutorials.