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.1.8.tar.gz (13.3 kB view details)

Uploaded Source

Built Distribution

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

Uploaded Python 3

File details

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

File metadata

  • Download URL: diot-0.1.8.tar.gz
  • Upload date:
  • Size: 13.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.5.1 CPython/3.11.3 Linux/5.15.0-1038-azure

File hashes

Hashes for diot-0.1.8.tar.gz
Algorithm Hash digest
SHA256 21408f8a09628bfb8c88791eaab1558a71692adff4e237c96b4b31a54d3cb2f5
MD5 f50f9683312692923867cf6691cd1c17
BLAKE2b-256 76491ffeb0e2ccc0e56f79193d70f924ebb4880f78a4ae72cfa97ca85b084319

See more details on using hashes here.

File details

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

File metadata

  • Download URL: diot-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 11.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.5.1 CPython/3.11.3 Linux/5.15.0-1038-azure

File hashes

Hashes for diot-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 f2d7d2f121e8a60cd06b7d1b476765e25c37002d0db44e0f5ef72dca98d22640
MD5 e9b3bdecd885c7a91f912ae12100667f
BLAKE2b-256 cd0fc42a37189a2d7b3179c74a253e42f90ea24998ee88c6b5f3cad14bf74b11

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