Properties
Expose managed attributes with the @property decorator.
Syntax
@property
def area(self):
...A property lets a method be accessed like an attribute — no parentheses. It is perfect for computed values or for validating data when it is set.
How it works
- Decorate a method with
@propertyto make it a read-only attribute. - Add a matching
@name.setterto control assignment.
Example
class Circle:
def __init__(self, radius):
self.radius = radius
@property
def area(self):
return 3.14159 * self.radius ** 2
c = Circle(2)
print(round(c.area, 2))
# Output:
# 12.57When to use it
- A Temperature class exposes 'celsius' and 'fahrenheit' as properties that stay in sync automatically.
- A User class validates and normalises an email address whenever the 'email' property is set.
- A read-only 'full_name' property computes first + last name without allowing direct assignment.
More examples
Read-only property
Defines a computed, read-only property area that is accessed like an attribute, not a method call.
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def area(self):
return 3.14159 * self._radius ** 2
c = Circle(5)
print(c.area) # 78.53975
# c.area = 10 # AttributeError: can't setProperty with setter validation
Uses a setter to validate the value before storing it, raising an error for physically impossible temperatures.
class Temperature:
def __init__(self, celsius):
self.celsius = celsius
@property
def celsius(self):
return self._celsius
@celsius.setter
def celsius(self, value):
if value < -273.15:
raise ValueError('Below absolute zero')
self._celsius = value
t = Temperature(25)
print(t.celsius) # 25
t.celsius = 100 # OK
print(t.celsius) # 100Computed property pair
Provides two computed properties that derive their values from stored width and height attributes.
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
@property
def area(self):
return self.width * self.height
@property
def is_square(self):
return self.width == self.height
r = Rectangle(4, 4)
print(r.area) # 16
print(r.is_square) # True
Discussion