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

Uploaded Source

Built Distribution

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

Uploaded Python 3

File details

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

File metadata

  • Download URL: diot-0.2.2.tar.gz
  • Upload date:
  • Size: 13.4 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.2.2.tar.gz
Algorithm Hash digest
SHA256 ecb0123a8295ce3403ad3d194bc16d2593e8ee9377600e8d1a2fb6190ec8a388
MD5 464f4200bc683431ae13b0f208b61769
BLAKE2b-256 9e77f82f172bfab519a0512fa97907caa9a4d482bd78fe8c57a90c8b213b228d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: diot-0.2.2-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.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 8e2bc7191fe84948b587bb6bd132b08be66019667338d97a4168cc5bdcb0c55a
MD5 a7f51b1db2bd00ff48bb71b9d92db276
BLAKE2b-256 c813dfc2cc0f668f9e62bd4a612360664bd6180318b8f5a0c2c296decf736cc5

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