Skip to main content

Python dictionary with dot notation.

Project description

Logo

pypi tag codacy quality coverage pyver building docs

Python dictionary with dot notation (A re-implementation of python-box with some issues fixed and simplified)

from diot import Diot

movie_data = {
  "movies": {
    "Spaceballs": {
      "imdb stars": 7.1,
      "rating": "PG",
      "length": 96,
      "director": "Mel Brooks",
      "stars": [{"name": "Mel Brooks", "imdb": "nm0000316", "role": "President Skroob"},
                {"name": "John Candy","imdb": "nm0001006", "role": "Barf"},
                {"name": "Rick Moranis", "imdb": "nm0001548", "role": "Dark Helmet"}
      ]
    },
    "Robin Hood: Men in Tights": {
      "imdb stars": 6.7,
      "rating": "PG-13",
      "length": 104,
      "director": "Mel Brooks",
      "stars": [
                {"name": "Cary Elwes", "imdb": "nm0000144", "role": "Robin Hood"},
                {"name": "Richard Lewis", "imdb": "nm0507659", "role": "Prince John"},
                {"name": "Roger Rees", "imdb": "nm0715953", "role": "Sheriff of Rottingham"},
                {"name": "Amy Yasbeck", "imdb": "nm0001865", "role": "Marian"}
      ]
    }
  }
}

# Box is a conversion_box by default, pass in `conversion_box=False` to disable that behavior
# Explicitly tell Diot to convert dict/list inside
movie_diot = Diot(movie_data)

movie_diot.movies.Robin_Hood_Men_in_Tights.imdb_stars
# 6.7

movie_diot.movies.Spaceballs.stars[0].name
# 'Mel Brooks'

# Different as box, you have to use Diot for new data in a list
movie_diot.movies.Spaceballs.stars.append(
	Diot({"name": "Bill Pullman", "imdb": "nm0000597", "role": "Lone Starr"}))
movie_diot.movies.Spaceballs.stars[-1].role
# 'Lone Starr'

Install

pip install -U diot

API

https://pwwang.github.io/diot/api/diot/

Usage

Diot

Instantiated the same ways as dict

Diot({'data': 2, 'count': 5})
Diot(data=2, count=5)
Diot({'data': 2, 'count': 1}, count=5)
Diot([('data', 2), ('count', 5)])

# All will create
# Diot([('data', 2), ('count', 5)], diot_nest = True, diot_transform = 'safe')

Same as python-box, Diot is a subclass of dict which overrides some base functionality to make sure everything stored in the dict can be accessed as an attribute or key value.

diot = Diot({'data': 2, 'count': 5})
diot.data == diot['data'] == getattr(diot, 'data')

By default, diot uses a safe transformation to transform keys into safe names that can be accessed by diot.xxx

dt = Diot({"321 Is a terrible Key!": "yes, really"})
dt._321_Is_a_terrible_Key_
# 'yes, really'

Different as python-box, duplicate attributes are not allowed.

dt = Diot({"!bad!key!": "yes, really", ".bad.key.": "no doubt"})
# KeyError

Use different transform functions:

dt = Diot(oneTwo = 12, diot_transform = 'snake_case')
# or use alias:
# dt = SnakeDiot(oneTwo = 12)
dt.one_two == dt['one_two'] == dt['oneTwo'] == 12

dt = Diot(one_two = 12, diot_transform = 'camel_case')
# or use alias:
# dt = CamelDiot(one_two = 12)
dt.oneTwo == dt['one_two'] == dt['oneTwo'] == 12

dt = Diot(one_two = 12, diot_transform = 'upper')
dt.ONE_TWO == dt['one_two'] == dt['ONETWO'] == 12

dt = Diot(ONE_TWO = 12, diot_transform = 'lower')
dt.one_two == dt['ONE_TWO'] == dt['one_two'] == 12

Use your own transform function:

import inflection

dt = Diot(post = 10, diot_transform = inflection.pluralize)
dt.posts == dt['posts'] == dt['post'] == 10

OrderedDiot

diot_of_order = OrderedDiot()
diot_of_order.c = 1
diot_of_order.a = 2
diot_of_order.d = 3

list(diot_of_order.keys()) == ['c', 'a', 'd']

# insertion allowed for OrderedDiot
od = OrderedDiot()
od.insert(0, "c", "d")
od.insert(None, "x", "y")
od.insert_before('c', "e", "f")
od.insert_after("a", ("g", "h"))

od2 = OrderedDiot()
od2.a1 = 'b1'
od2.c1 = 'd1'
od.insert(-1, od2)

od3 = OrderedDiot()
od3.a2 = 'b2'
od3.c2 = 'd2'
od.insert_before('c', od3)

FrozenDiot

fd = FrozenDiot(a=1, b=3)
fd.c = 3 # DiotFrozenError
with fd.thaw():
    fd.c = 3
fd.c == 3

Missing key handler

d = Diot(a=1, b=2, diot_missing=ValueError)
d['c'] # ValueError
d.c # AttributeError from ValueError

d = Diot(a=1, b=2, diot_missing=ValueError("Custom message"))

d = Diot(a=1, b=2, diot_missing=None)
# d.c is None

d = Diot(a=1, b=2, diot_missing=lambda key, diot: diot.a + diot.b)
# d.c == 3

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

diot-0.2.3.tar.gz (13.4 kB view details)

Uploaded Source

Built Distribution

diot-0.2.3-py3-none-any.whl (11.5 kB view details)

Uploaded Python 3

File details

Details for the file diot-0.2.3.tar.gz.

File metadata

  • Download URL: diot-0.2.3.tar.gz
  • Upload date:
  • Size: 13.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.11.6 Linux/6.2.0-1014-azure

File hashes

Hashes for diot-0.2.3.tar.gz
Algorithm Hash digest
SHA256 0b8ccbe3813acda67665ea9025d4eea7f73b2df4e2ab16c5c3f1da8b0dbba4cf
MD5 d9e773e1e0992a161fc2c369d61ee71a
BLAKE2b-256 a7cf60841b2d548049a778ff2791648d66c49c39733cefbfdac5e4f6f7b22c41

See more details on using hashes here.

File details

Details for the file diot-0.2.3-py3-none-any.whl.

File metadata

  • Download URL: diot-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 11.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.11.6 Linux/6.2.0-1014-azure

File hashes

Hashes for diot-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 defd4556bd961327cbfd497f63fcb9d0d79a649bbc8932f26d94dd25a7832e1c
MD5 eb3366fe4cd537bceea6886d2990a161
BLAKE2b-256 8e3498edb1a36df6dda6ebaa100e54e65dde5ccfb85e6efd0d7c23113c9604ef

See more details on using hashes here.

Supported by

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