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

Uploaded Source

Built Distribution

diot-0.1.5-py3-none-any.whl (11.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: diot-0.1.5.tar.gz
  • Upload date:
  • Size: 13.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.11 CPython/3.10.0 Linux/5.11.0-1020-azure

File hashes

Hashes for diot-0.1.5.tar.gz
Algorithm Hash digest
SHA256 a8adc50e2d8e2a1d03ed017ecae98eb09a7ebb3bd0a5fbd44cbfb222e5a71bb4
MD5 34d5f7a6d1a5aedca0dd1b840dc7d359
BLAKE2b-256 8ec48cd645c127977b4072e02759dc9d92afd8b76a2b2080ff533bbca685cea1

See more details on using hashes here.

File details

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

File metadata

  • Download URL: diot-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 11.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.11 CPython/3.10.0 Linux/5.11.0-1020-azure

File hashes

Hashes for diot-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 f5e90a405064c09873130240b0c3a2ba9a480e754611a74f93599f84ec0a28b9
MD5 4c49fa0e17c58c5f56daef88c9da92a9
BLAKE2b-256 9117735eb410606419f2c160f63cb3ab19f3625749290a7405cd9d6243e36be1

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