Property Manager
The `property-manager` package, currently at version 3.0, provides useful property variants for Python programming, extending Python's built-in `property` descriptor. It offers decorators for creating required properties, writable properties, and cached properties, as well as a `PropertyManager` base class with enhanced constructor behavior and `repr()` customization. The library has a stable release cadence, with version 3.0 released in 2020, and is designed to make managing class attributes more robust and flexible.
Warnings
- gotcha Classes inheriting from `PropertyManager` will raise a `TypeError` during instantiation if a `required_property` is not provided as a keyword argument to the constructor.
- gotcha The `cached_property` in `property-manager` does not support threading or time-based cache invalidation, unlike some other cached property implementations (e.g., `cached-property` library). If you need these features, consider alternatives or implement custom cache invalidation logic.
- gotcha Values for `writable_property` instances on `PropertyManager` subclasses can be set directly via keyword arguments during object instantiation. This can lead to unexpected behavior if not accounted for when designing constructors or expecting properties to always start with their computed defaults.
Install
-
pip install property-manager
Imports
- PropertyManager
from property_manager import PropertyManager
- writable_property
from property_manager import writable_property
- required_property
from property_manager import required_property
- cached_property
from property_manager import cached_property
Quickstart
from property_manager import PropertyManager, required_property, writable_property, cached_property
import random
class MyManagedObject(PropertyManager):
@required_property
def name(self):
"""A name that must be provided during initialization."""
pass
@writable_property
def value(self):
"""A writable property with a computed default."""
return random.randint(1, 100)
@cached_property
def expensive_calculation(self):
"""A property whose value is computed once and cached."""
print("Calculating expensive_calculation...")
return sum(range(self.value * 1000))
# Instantiate with a required property
obj = MyManagedObject(name="Example Item")
# Access writable property (gets default initially)
print(f"Initial value: {obj.value}")
# Set writable property
obj.value = 200
print(f"New value: {obj.value}")
# Access cached property (computes once)
print(f"Expensive calculation (first access): {obj.expensive_calculation}")
print(f"Expensive calculation (second access): {obj.expensive_calculation}")
# Attempt to create an object without a required property
try:
MyManagedObject()
except TypeError as e:
print(f"Caught expected error: {e}")