Add dot notation to Python dicts.
Project description
dotdict3
A lightweight Python package for accessing dictionary keys and list elements using dot notation with automatic recursive conversion of nested structures.
Installation
pip install dotdict3
>>> from dotdict3 import DotDict
>>> d = DotDict({"a": "b"})
>>> d.a
'b'
Features
- Dot notation access: Access dictionary keys as attributes (
data.keyinstead ofdata['key']) - Automatic conversion: Nested dictionaries and iterables are automatically converted to
DotDictandDotList - Recursive processing: Works seamlessly with deeply nested structures
- Standard compatibility: Fully compatible with built-in
dictandlistoperations
Quick Start
from dotdict3 import DotDict
data = DotDict({
'name': 'John',
'age': 30,
'address': {
'city': 'New York',
'zipcode': '10001'
}
})
# Access with dot notation
print(data.name) # 'John'
print(data.address.city) # 'New York'
# Still works with bracket notation
print(data['age']) # 30
Classes
DotDict
A dictionary subclass that allows attribute-style access to keys.
Features
- Attribute access: Get, set, and delete keys using dot notation
- Automatic nesting: Nested dictionaries are automatically converted to
DotDict - Iterable conversion: Lists, tuples, sets, and ranges are converted to
DotList - Dict compatibility: All standard
dictmethods work as expected
Usage
from dotdict3 import DotDict
# Basic usage
user = DotDict({'name': 'Alice', 'role': 'admin'})
print(user.name) # 'Alice'
# Setting values
user.email = 'alice@example.com'
print(user.email) # 'alice@example.com'
# Nested dictionaries
config = DotDict({
'database': {
'host': 'localhost',
'port': 5432
}
})
print(config.database.host) # 'localhost'
# Deleting keys
del user.role
DotList
A list subclass that automatically converts nested dictionaries and iterables.
Features
- Automatic conversion: Dictionaries in the list become
DotDictinstances - Nested iterables: Lists, tuples, sets, and ranges become
DotListinstances - List compatibility: All standard
listmethods work as expected
Usage
from dotdict3 import DotList
# Basic usage
items = DotList([1, 2, 3])
print(items[0]) # 1
# Lists with dictionaries
users = DotList([
{'name': 'Alice', 'age': 30},
{'name': 'Bob', 'age': 25}
])
print(users[0].name) # 'Alice'
# Nested lists
matrix = DotList([[1, 2], [3, 4]])
print(matrix[0][1]) # 2
# Appending
users.append({'name': 'Charlie', 'age': 35})
print(users[2].name) # 'Charlie'
Advanced Usage
Complex Nested Structures
from dotdict3 import DotDict
data = DotDict({
'users': [
{
'name': 'Alice',
'scores': [95, 87, 92],
'metadata': {
'joined': '2024-01-01',
'tags': ['admin', 'active']
}
},
{
'name': 'Bob',
'scores': [88, 90, 85],
'metadata': {
'joined': '2024-02-15',
'tags': ['user']
}
}
],
'settings': {
'theme': 'dark',
'notifications': True
}
})
# Access deeply nested data
print(data.users[0].name) # 'Alice'
print(data.users[0].scores[1]) # 87
print(data.users[0].metadata.tags[0]) # 'admin'
print(data.settings.theme) # 'dark'
Working with JSON
Perfect for working with JSON data:
import json
from dotdict3 import DotDict
# Load JSON
with open('config.json') as f:
config = DotDict(json.load(f))
# Access nested configuration
db_host = config.database.host
api_key = config.api.credentials.key
Dynamic Updates
from dotdict3 import DotDict
data = DotDict({})
# Add nested structure dynamically
data['user'] = {
'profile': {
'name': 'Alice',
'preferences': ['email', 'sms']
}
}
# Automatically converted
print(data.user.profile.name) # 'Alice'
print(data.user.profile.preferences[0]) # 'email'
Important Notes
Reserved Names
Be careful with dictionary method names. Since DotDict inherits from dict, built-in method names will shadow your keys:
data = DotDict({'items': [1, 2, 3]})
# This returns the dict.items() method, not your data!
print(data.items) # <built-in method items>
# Use bracket notation instead
print(data['items']) # DotList([1, 2, 3])
Common reserved names to avoid:
clearcopygetitemskeyspopsetdefaultupdatevalues
Type Checking
The classes include automatic type checking to prevent double conversion:
from dotdict3 import DotDict
inner = DotDict({'a': 1})
outer = DotDict({'inner': inner})
# inner is not converted again
assert outer['inner'] is inner # True
Iterable Conversion
All iterables (except strings and bytes) are converted to DotList:
data = DotDict({
'list': [1, 2, 3],
'tuple': (4, 5, 6),
'set': {7, 8, 9},
'range': range(10, 13)
})
# All become DotList
assert isinstance(data['list'], DotList) # True
assert isinstance(data['tuple'], DotList) # True
assert isinstance(data['set'], DotList) # True
assert isinstance(data['range'], DotList) # True
Compatibility
- Python 3.6+
- Compatible with all standard
dictandlistoperations
Use Cases
- Configuration management: Easy access to nested config files
- API responses: Simplify working with JSON API responses
- Data processing: Cleaner code when working with nested data structures
- Settings objects: Create intuitive settings/options objects
Limitations
- String keys only (dictionary keys must be valid Python identifiers for dot notation)
- Watch out for reserved dictionary/list method names
- Dot notation won't work for keys with spaces or special characters
License
MIT License
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Examples
Example 1: Configuration File
from dotdict3 import DotDict
import yaml
with open('config.yaml') as f:
config = DotDict(yaml.safe_load(f))
# Easy access to nested config
database_url = f"{config.database.host}:{config.database.port}"
log_level = config.logging.level
Example 2: API Response
from dotdict3 import DotDict
import requests
response = requests.get('https://api.example.com/users/1')
user = DotDict(response.json())
print(f"{user.name} - {user.email}")
print(f"City: {user.address.city}")
Example 3: Test Data
from dotdict3 import DotDict
test_data = DotDict({
'scenarios': [
{'name': 'happy_path', 'expected': 200},
{'name': 'not_found', 'expected': 404},
{'name': 'server_error', 'expected': 500}
]
})
for scenario in test_data.scenarios:
assert response.status_code == scenario.expected
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dotdict3-1.4.1.tar.gz.
File metadata
- Download URL: dotdict3-1.4.1.tar.gz
- Upload date:
- Size: 6.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ff249808188d3a71ffcac3cb146267cf1492384c6e9e81d0999402520af7804
|
|
| MD5 |
b706f45259d29eb7a60c2e6e8ec63cf0
|
|
| BLAKE2b-256 |
b4b87af7881a2f26d4e18502642e055d4ee3a14c780cf2a8e0b6ab1edc7a1ab3
|
File details
Details for the file dotdict3-1.4.1-py3-none-any.whl.
File metadata
- Download URL: dotdict3-1.4.1-py3-none-any.whl
- Upload date:
- Size: 5.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ed15121532422d20317c1512e177ac13daf74cec15cf04b80cef1f3e6ce8821
|
|
| MD5 |
3b27da54641fbd66c40e0a4f8cae98cd
|
|
| BLAKE2b-256 |
5ba0a12af68e4b9eaa6be004112e2658d5f767adb33ea594a842189cc283621c
|