MetaDict is a powerful dict subclass enabling (nested) attribute-style item access/assignment and IDE autocompletion support.
Project description
MetaDict
Enabling dot notation and IDE autocompletion
Installation • Features • Documentation • Competitors • Citation
MetaDict is designed to behave exactly like a dict
while enabling (nested) attribute-style key access/assignment with IDE autocompletion support.
Many libraries claim to do the same, but fail in different ways (see Competitors).
Installation
$ pip install metadict
Features
- Attribute-style key access and assignment (dot notation) with IDE autocompletion support
from metadict import MetaDict cfg = MetaDict() cfg.optimizer = 'Adam' print(cfg.optimizer) >> Adam
- Nested key assignment similar to
defaultdict
fromcollections
cfg = MetaDict(nested_assignment=True) cfg.model.type = 'Transformer' print(cfg.model.type) >> Transformer # or restrict nested assignment via context manager cfg = MetaDict() with cfg.enabling_nested_assignment() as cfg: cfg.model.type = 'Transformer' cfg.new_model.type = 'MLP' >> AttributeError: 'MetaDict' object has no attribute 'new_model'
- Is a
dict
dict_config = {'model': 'Transformer', 'optimizer': 'Adam'} cfg = MetaDict(dict_config) print(isinstance(cfg, dict)) >> True print(cfg == dict_config) >> True
- Inbuilt
json
supportimport json cfg = MetaDict({'model': 'Transformer'}) print(json.loads(json.dumps(cfg))) >> {'model': 'Transformer'}
- Recursive conversion to
dict
cfg = MetaDict({'models': [{'name': 'Transformer'}, {'name': 'MLP'}]}) print(cfg.models[0].name) >> Transformer cfg_dict = cfg.to_dict() print(type(cfg_dict['models'][0])) >> <class 'dict'> # Note: Appending a `dict` to a list within a `MetaDict` does not convert the `dict`. # MetaDict does not overwrite `list` so intercepting `append`. `extend`, etc. is currently not possible. # Simply wrap the appended or extended `dict` as a `MetaDict`. cfg.models.append({'name': 'RNN'}) print(isinstance(cfg.models[-1], MetaDict)) >> False cfg.models.append(MetaDict({'name': 'RNN'})) print(isinstance(cfg.models[-1], MetaDict)) >> True
- No namespace conflicts with inbuilt methods like
items()
,update()
, etc.cfg = MetaDict() # Key 'items' is assigned as in a normal dict, but a UserWarning is raised cfg.items = [1, 2, 3] >> UserWarning: 'MetaDict' object uses 'items' internally. 'items' can only be accessed via `obj['items']`. print(cfg) >> {'items': [1, 2, 3]} print(cfg['items']) >> [1, 2, 3] # But the items method is not overwritten! print(cfg.items) >> <bound method Mapping.items of {'items': [1, 2, 3]}> print(list(cfg.items())) >> [('items', [1, 2, 3])]
- References are preserved
params = [1, 2, 3] cfg = MetaDict({'params': params}) print(cfg.params is params) >> True model_dict = {'params': params} cfg = MetaDict(model=model_dict) print(cfg.model.params is params) >> True # Note: dicts are recursively converted to MetaDicts, thus... print(cfg.model is model_dict) >> False print(cfg.model == model_dict) >> True
Documentation
Check the Test Cases for a complete overview of all MetaDict features.
Competitors
- Addict
- No key autocompletion in IDE
- Nested key assignment cannot be turned off
- Newly assigned
dict
objects are not converted to support attribute-style key access - Shadows inbuilt type
Dict
- Prodict
- No key autocompletion in IDE without defining a static schema (similar to
dataclass
) - No recursive conversion of
dict
objects when embedded inlist
or other inbuilt iterables
- No key autocompletion in IDE without defining a static schema (similar to
- AttrDict
- No key autocompletion in IDE
- Converts
list
objects totuple
behind the scenes
- Munch
- Inbuilt methods like
items()
,update()
, etc. can be overwritten withobj.items = [1, 2, 3]
- No recursive conversion of
dict
objects when embedded inlist
or other inbuilt iterables
- Inbuilt methods like
- EasyDict
- Only strings are valid keys, but
dict
accepts all hashable objects as keys - Inbuilt methods like
items()
,update()
, etc. can be overwritten withobj.items = [1, 2, 3]
- Inbuilt methods don't behave as expected:
obj.pop('unknown_key', None)
raises anAttributeError
- Only strings are valid keys, but
Citation
@article{metadict,
title = {MetaDict - Enabling dot notation and IDE autocompletion},
author = {Hillebrand, Lars},
year = {2022},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/LarsHill/metadict}},
}
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
Built Distribution
File details
Details for the file metadict-0.1.3.tar.gz
.
File metadata
- Download URL: metadict-0.1.3.tar.gz
- Upload date:
- Size: 6.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.9.15
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9a3164027facef1a1d24412152a8ffe6172446f1306b5ea9774c546459bd3aa7 |
|
MD5 | 2d679cd1996eddb0a086743eaa3e56e0 |
|
BLAKE2b-256 | 647cce388d73ece8963a30cab5cd095e6c5d7410c9027c475ccb424809f95c7b |
File details
Details for the file metadict-0.1.3-py3-none-any.whl
.
File metadata
- Download URL: metadict-0.1.3-py3-none-any.whl
- Upload date:
- Size: 11.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.9.15
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 177ec84941fac3a18ecfb3b7ac29543826a186568b5f47ad348d6eae38c28c75 |
|
MD5 | c6d832456eac8f235c4fefe64e5742c8 |
|
BLAKE2b-256 | c7b5c893b93df898461a814d592b1beab344629297122f1749f9ad114728c528 |