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
Metadata
Release files for diot 0.3.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| diot-0.3.4.tar.gz | 69.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| diot-0.3.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 82.3 kB
Release files / diot-0.3.4.tar.gz
| Download URL | diot-0.3.4.tar.gz |
|---|---|
| Size | 69.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
803c26c02d9693c568d77cc0948e9589efcabc5014ebda37403ccb4521bd342a
|
|
BLAKE2b-256 checksum How to use checksums |
93e2c041c3bcbaa87fb3e117be04792ba8fc6a6c9a161f107effcf548f6b492e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / diot-0.3.4-py3-none-any.whl
| Download URL | diot-0.3.4-py3-none-any.whl |
|---|---|
| Size | 12.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cbb067ae23711c0a7e5f0145a7c278c015cd57f805b2247ece59fa6f02538cf9
|
|
BLAKE2b-256 checksum How to use checksums |
f314dff86a4da974833814bb58f1e5905b915c60aba59375fd415b6bca90f654
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|