DictPath
DictPath provides an object-oriented way to navigate and manipulate nested dictionaries using path-like expressions. It allows for robust and type-safe access to dictionary values, supporting various path syntaxes and advanced traversal features. The current stable version is 0.5.0, with a release cadence that has recently seen significant updates focused on API enhancements and performance.
Warnings
- breaking Version 0.5.0 and later now require Python 3.8+. Previous versions (0.1.x) supported Python 2.7 and a broader range of Python 3 versions. Applications on older Python versions must update their environment or stick to `dictpath<0.5.0`.
- breaking The `BaseAccessor` class was replaced by `NodeAccessor` in the 0.5.0 release series (specifically from 0.5.0a3). Direct usage or subclassing of `BaseAccessor` will lead to `NameError` or `ImportError`.
- breaking The `AccessorPath` class became generic in the 0.5.0 release series (specifically from 0.5.0a3). This change primarily affects type hints and advanced usage involving generics, potentially breaking existing type annotations or specific instantiation patterns.
- gotcha Version 0.5.0 introduced "Expanded parsing and typing guarantees," which might mean stricter validation of path strings. Paths that were previously tolerated but ambiguous or malformed might now raise errors.
Install
-
pip install dictpath
Imports
- AccessorPath
from dictpath import AccessorPath
Quickstart
from dictpath import AccessorPath
data = {
'user': {
'profile': {
'name': 'Alice',
'age': 30,
'contact': [
{'type': 'email', 'value': 'alice@example.com'},
{'type': 'phone', 'value': '123-456-7890'}
]
}
}
}
# Create a path accessor
path = AccessorPath('user.profile.name')
# Read a value
name = path.read_value(data)
print(f"User name: {name}")
# Access a nested list item
email_path = AccessorPath('user.profile.contact.0.value')
email = email_path.read_value(data)
print(f"User email: {email}")
# Using subscriptable accessors (0.5.0+)
phone_path = AccessorPath('user')['profile']['contact'][1]['value']
phone = phone_path.read_value(data)
print(f"User phone: {phone}")
# Getting a default value if path doesn't exist
missing_path = AccessorPath('user.profile.address')
address = missing_path.read_value(data, default='No address provided')
print(f"User address: {address}")