Skip to main content

A dotdict implementation for Python

Project description

Dotdict (dotdict-tool)

A tiny, convenient wrapper around Python's dict that lets you access keys via dot notation while preserving normal dict behavior. Nested dicts (and dicts inside lists) are auto-wrapped into Dotdict on access.

Works great for quick data access in scripts, small apps, and anywhere you want ergonomic attribute-style access without bringing in heavy dependencies.

Installation

pip install dotdict-tool

Quick start

from Dotdict import Dotdict

data = {
    "name": "Bao",
    "age": 30,
    "address": {"city": "HCMC", "country": "Vietnam"}
}

# Convert sang Dotdict
d = Dotdict(data)

print(d.name)            # Bao
print(d.age)             # 30
print(d.address.city)    # HCMC

Key features

  • Dot notation access: d.user.name instead of d["user"]["name"].
  • Auto-wrap nested dicts: Nested dicts become Dotdict on access.
  • List support: Dicts inside lists are wrapped on access (d.items[0].id).
  • Missing keys are safe: Accessing a missing key returns a readable placeholder string instead of raising an error.
  • Still a real dict: Inherits from dict; you can use all standard dict methods (keys, items, get, update, ...).

Behavior and API

  • Attribute access and assignment

    • d.attr is equivalent to d["attr"].
    • d.attr = value is equivalent to d["attr"] = value.
  • Auto-wrapping on read

    • When you read a key:
      • If the value is a dict, it is replaced in-place with Dotdict(value) and returned.
      • If the value is a list, any dict elements inside are converted in-place to Dotdict.
  • Missing keys

    • Accessing a missing key returns the string pattern "[~~missing-key-<key>~~]".
    • Example:
      d = Dotdict({})
      print(d.username)  # [~~missing-key-username~~]
      
  • Standard dict behavior

    • All regular dict operations are supported: iteration, membership checks, updates, etc.
    • Example:
      for key, value in d.items():
          print(key, value)
      d.update({"role": "admin"})
      

Edge cases and tips

  • Key name clashes with dict attributes

    • If a key name matches a dict attribute/method (e.g., keys, items, get), attribute access will refer to the dict method, not your value. Use index access in such cases:
      d = Dotdict({"keys": [1, 2, 3]})
      d.keys            # <built-in method keys of Dotdict object>
      d["keys"]        # [1, 2, 3]
      
  • Converting back to plain dicts

    • dict(d) returns a shallow dict, but nested values remain Dotdict where present. For a deep conversion:
      def to_plain_dict(obj):
          if isinstance(obj, Dotdict):
              return {k: to_plain_dict(v) for k, v in obj.items()}
          if isinstance(obj, list):
              return [to_plain_dict(v) for v in obj]
          return obj
      
      plain = to_plain_dict(d)
      
  • Serialization

    • Dotdict is JSON-serializable as long as the underlying values are. If you need to ensure no Dotdict instances are present, run the deep conversion above first.

Additional examples

# Attribute assignment
d = Dotdict({})
d.user = {"name": "Bao"}     # auto-wraps on read
print(d.user.name)             # Bao

# Lists of dicts
d = Dotdict({"items": [{"id": 1}, {"id": 2}]})
print(d.items[0].id)           # 1
print(d.items[1].id)           # 2

# Mixing attribute and index access
profile = Dotdict({"name": "Bao", "links": {"github": "https://github.com/..."}})
print(profile["name"])        # Bao
print(profile.links.github)    # https://github.com/...

Import path

  • After install via pip: from Dotdict import Dotdict
  • Inside this repository (editable install): still from Dotdict import Dotdict

Requirements

  • Python 3.10+

Contributing

Issues and pull requests are welcome. If you spot an edge case or want to propose improvements (e.g., optional strict mode, opt-out of missing-key placeholder), open an issue first to discuss.

Disclaimer

Dotdict trades a bit of strictness for convenience. Prefer explicit key access in production-critical or highly dynamic domains where silent fallbacks could hide errors.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dotdict_tool-0.1.2.tar.gz (3.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dotdict_tool-0.1.2-py3-none-any.whl (2.9 kB view details)

Uploaded Python 3

File details

Details for the file dotdict_tool-0.1.2.tar.gz.

File metadata

  • Download URL: dotdict_tool-0.1.2.tar.gz
  • Upload date:
  • Size: 3.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.0

File hashes

Hashes for dotdict_tool-0.1.2.tar.gz
Algorithm Hash digest
SHA256 ae6b1108cc6d3e26d9f4c8dcf707b59ee9c992bba187c6dc1863708d84d87bf8
MD5 3faaa67f6da8ee18f58952b342107054
BLAKE2b-256 6d9ba541f2914351cc303ab8f3efa63eaa41dd779ff6aa8b31687aac7744e162

See more details on using hashes here.

File details

Details for the file dotdict_tool-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: dotdict_tool-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 2.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.0

File hashes

Hashes for dotdict_tool-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 030a258ef69b077ec2e754f64c3df3aa59702372a0b84b7e1f8d82c514bba759
MD5 aa3bfa0dce4ed18e5c4f53a5ecf6f566
BLAKE2b-256 62b4c951c7d5a8c3724da88e2907c60f6b96505d454f678ef4f690622dacdf00

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page