Add property getter setter validation in Python
Shows how to use @property with a setter to validate values before assigning them in a Python class.
Python code
37 linesclass Temperature:
def __init__(self, celsius=0):
self._celsius = celsius # Use underscore to avoid recursion
@property
def celsius(self):
"""Getter returns the stored value."""
return self._celsius
@celsius.setter
def celsius(self, value):
"""Setter validates before storing."""
if not isinstance(value, (int, float)):
raise TypeError("Temperature must be a number")
if value < -273.15:
raise ValueError("Temperature cannot be below absolute zero")
self._celsius = value
@property
def fahrenheit(self):
"""Derived property with getter only."""
return self._celsius * 9/5 + 32
if __name__ == "__main__":
temp = Temperature()
temp.celsius = 25
print(f"Celsius: {temp.celsius}, Fahrenheit: {temp.fahrenheit}")
try:
temp.celsius = -300
except ValueError as e:
print(f"Validation error: {e}")
try:
temp.celsius = "hot"
except TypeError as e:
print(f"Type error: {e}")
Output
Celsius: 25, Fahrenheit: 77.0
Validation error: Temperature cannot be below absolute zero
Type error: Temperature must be a number
How it works
The @property decorator turns a method into a read-only attribute. The setter allows custom validation on assignment, raising TypeError for wrong types and ValueError for out-of-range values. Using an underscore prefix (_celsius) for the internal attribute prevents recursion because the setter is bypassed during __init__. The fahrenheit property is derived and has no setter, so it's read-only.
Common mistakes
- Forgetting to use an underscore for the internal attribute, causing infinite recursion.
- Not validating types or ranges, allowing invalid data to be stored.
- Trying to set a read-only property (like fahrenheit) without defining a setter.
Variations
- Use `@celsius.deleter` to handle deletion of the property.
- Use `dataclasses` with custom `__post_init__` validation instead.
Real-world use cases
- Validating user input in a settings object before it's applied.
- Ensuring sensor readings stored in a data model stay within physical limits.
- Enforcing business rules on financial fields like non-negative balances.
Sponsored
More from OOP & classes
- Binary Tree Inorder Traversal in Python easy
- Borg pattern shared state in Python medium
- Bridge Pattern in Python: Separate Abstraction from Implementation medium
- Composable Predicates with the &, |, ~ Operators in Python medium
- Composition over Inheritance: How to Build a Wallet Account in Python easy
- Compute Derived Fields with @dataclass __post_init__ in Python easy
Keep learning
Related tutorials and quizzes for this topic.