DotDict
DotDict
Section titled “DotDict”DotDict is a dictionary subclass that enables attribute-style access to dictionary keys. Instead of writing config["database"]["host"], you can write config.database.host. Nested plain dictionaries are automatically converted to DotDict instances on access, making the entire tree navigable with dot notation.
This utility is especially useful when working with configuration data, API responses, or any deeply nested dictionary structure where bracket notation becomes verbose and hard to read.
Import
Section titled “Import”from orionis.support.wrapper.dot_dict import DotDictCreating an Instance
Section titled “Creating an Instance”DotDict supports the same initialization signatures as a standard dict:
# From a dictionaryconfig = DotDict({"database": {"host": "localhost", "port": 5432}})
# From keyword argumentssettings = DotDict(debug=True, version="1.0")
# Empty instancedata = DotDict()Attribute Access
Section titled “Attribute Access”Reading Values
Section titled “Reading Values”Access dictionary keys as object attributes. Nested dictionaries are automatically wrapped in DotDict:
config = DotDict({ "app": { "name": "Orionis", "settings": { "debug": True } }})
config.app.name # "Orionis"config.app.settings.debug # TrueAccessing a key that does not exist returns None instead of raising an exception:
config = DotDict({"a": 1})config.missing_key # NoneSetting Values
Section titled “Setting Values”Assign values using attribute syntax. Plain dictionaries are automatically converted to DotDict:
config = DotDict()
config.name = "Orionis"config.database = {"host": "localhost", "port": 5432}
config.database.host # "localhost" — auto-converted to DotDictDeleting Values
Section titled “Deleting Values”Remove keys using the del statement:
config = DotDict({"key": "value"})del config.keyRaises AttributeError if the key does not exist:
config = DotDict()del config.nonexistent # AttributeError: 'DotDict' has no attribute 'nonexistent'Methods
Section titled “Methods”Retrieve a value by key with an optional default. Like attribute access, nested dicts are auto-converted:
config = DotDict({"timeout": 30, "retry": {"max": 3}})
config.get("timeout") # 30config.get("missing", 60) # 60config.get("missing") # Noneconfig.get("retry").max # 3export
Section titled “export”Convert the entire DotDict tree back to standard Python dictionaries — useful for serialization or passing data to libraries that expect plain dicts:
config = DotDict({"app": DotDict({"name": "Orionis", "meta": DotDict({"v": 1})})})
result = config.export()# {"app": {"name": "Orionis", "meta": {"v": 1}}}
type(result) # dict (not DotDict)type(result["app"]) # dict (not DotDict)Create a deep copy of the DotDict. Modifications to the copy do not affect the original:
original = DotDict({"nested": {"value": 10}})cloned = original.copy()
cloned.nested.value = 99original.nested.value # 10 — unchangedStandard Dict Compatibility
Section titled “Standard Dict Compatibility”DotDict inherits from dict, so all standard dictionary operations remain available:
config = DotDict({"a": 1, "b": 2, "c": 3})
# Bracket accessconfig["a"] # 1
# Membership test"a" in config # True"z" in config # False
# Iterationlist(config) # ["a", "b", "c"]
# Lengthlen(config) # 3
# Updateconfig.update({"d": 4})config.d # 4
# Reprrepr(config) # "{'a': 1, 'b': 2, 'c': 3, 'd': 4}"Deep Nesting
Section titled “Deep Nesting”Attribute access works seamlessly through any number of nesting levels. All intermediate plain dicts are automatically converted and cached:
data = DotDict({ "level1": { "level2": { "level3": { "value": "deep" } } }})
data.level1.level2.level3.value # "deep"
# Mutation at any depthdata.level1.level2.level3.value = "modified"data.level1.level2.level3.value # "modified"Conversion Behavior
Section titled “Conversion Behavior”Understanding when and how plain dicts are converted to DotDict is key to using this class effectively:
| Operation | Plain dict auto-converted? | Cached in-place? |
|---|---|---|
d.key (attribute read) | Yes | Yes |
d.key = {...} (attribute write) | Yes | — |
d.get("key") | Yes | Yes |
d["key"] (bracket read) | No | No |
d.copy() | Yes (deep) | — |
d.export() | Reverse — converts DotDict → dict | — |
Bracket-style access (d["key"]) does not auto-convert nested values. Use attribute access or get() when you need recursive DotDict behavior.